Java Hibernate对分离对象进行不必要的查询 [英] java Hibernate unnecessary queries on detached objects

查看:63
本文介绍了Java Hibernate对分离对象进行不必要的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用hibernate和c3p0连接池来插入,更新和删除许多分离的对象. 问题在于,hibernate不会批处理语句,而是会

I'm inserting, updating and deleting many detached objects with hibernate and a c3p0 connectionpool. The problem is that hibernate does not batch the statements but instead does a

select @@session.tx_read_only

在每个会话之间

持久/插入/更新/删除(对象).分析sql-connection看起来像这样:

between every session.persist/insert/update/delete(object). Profiling the sql-connection it looks like this:

select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only
insert...
select @@session.tx_read_only

使用select @@ session.tx_rad_only总是返回"0"(当然).我使用无状态会话还是无状态会话都没有关系.这样产生的性能是不可接受的,并且超出了任何预期.

with select @@session.tx_rad_only always returning "0" (of course). It doesn't matter whether i use a stateless or stateful session. The resulting performance is not acceptable and far of any expectation.

我的休眠配置:

 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:4040/xy?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">xy</property>
    <property name="hibernate.connection.password">xy</property>
    <property name="hibernate.connection.autocommit">false</property>
    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.format_sql">false</property>
    <property name="hibernate.use_sql_comments">false</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</property>
    <property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">300</property>
    <property name="hibernate.c3p0.max_statements">250</property>
    <property name="hibernate.c3p0.idle_test_period">3000</property>
    <property name="hibernate.jdbc.batch_size">250</property>
    <property name="hibernate.connection.release_mode">auto</property>
    <property name="hibernate.order_inserts">true</property>
    <property name="hibernate.order_updates">true</property>
    <property name="hibernate.cache.use_second_level_cache">false</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
    <property name="hibernate.cache.use_query_cache">true</property>
    <property name="net.sf.ehcache.configurationResourceName">hibernate_ehcache.xml</property>

我正在使用:

<dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>4.3.5.Final</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.31</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.3.4.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>ejb3-persistence</artifactId>
        <version>1.0.2.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>4.3.4.Final</version>
    </dependency>

我几乎没有冬眠的经历,这是一个很好的猜测,我犯了一个大错误,所以请随时提出任何建议. 我之所以转为休眠,是因为ORM功能来自简单的jdbc准备好的语句,具有出色的快速性能. MYSQL服务器处于良好的配置状态.

I have nearly no expirience with hibernate and it is a good guess i made a huge mistake so please feel free to suggest anything. I switched to hibernate because the ORM functionality and am coming from plain jdbc prepared statements with a blazing fast performance. The MYSQL-Server is in a good configuration-state.

edit1: 我知道: Hibernate中不必要的查询-MySql 我的实体中没有事务注释,也没有定义的隔离级别

edit1: i'm aware of: Unnecessary queries in Hibernate - MySql I've got no transactional annotations in my entities nor a defined isolationlevel anywhere

edit2: 我将connectionpool更改为bonecp-问题仍然存在.似乎显然是一个休眠的配置问题.

edit2: i changed my connectionpool to bonecp - and the problem continues. Seems to be clearly a hibernate copnfiguration issue.

edit3: 尝试了许多不同的方法,并发现了一些暗示: 如果我每5次插入一次session.flush()手动操作(例如,批量大小)[从休眠状态再次尝试批次示例(再次),则 select @@ session.tx_read_only 查询会出现两次-每5个查询.因此,我认为 select @@ session.tx_read_only 与刷新有关.有什么方法可以防止休眠刷新每个插入/更新? 到目前为止,我尝试了:session.setFlushMode(FlushMode.COMMIT/NEVER/etc),而行为没有任何变化.也许我没有正确配置任何内容...休眠触发什么来刷新每个插入内容?在表上的唯一约束?休眠验证框架?复杂的对象图?并发困难吗?也许是锁定问题(Hibernate不确定其他人是否锁定了表并且不进行批处理,但检查表是否为只读的每个插入吗?)?

edit3: tried many different things and found maybe a trace of a hint: If I manualy session.flush() every 5 inserts (=size of batch e.g.)[tried the batch-example AGAIN from hibernate], the select @@session.tx_read_only query appears double - every 5 queries. I therefore assume that select @@session.tx_read_only is related to flushing. are there any ways to prevent hibernate from flushing every single insert/update? I tried so far: session.setFlushMode(FlushMode.COMMIT/NEVER/etc) without any change in the behaviour. Maybe I misconfigured anything... what does hibernate trigger to flush every insert? Unique constraint at the tables? hibernate validation framework? complex object-graphs? difficult concurrency? maybe a locking issue (Hibernate isn't sure if someone else locked the tables and doesn't batch but checks every single insert if the table is read only?)?

我没有发现与此极端(我想是)潮红行为有关的东西.

i found nothing related to this extrem (I assume) flushing bahaviour.

推荐答案

我们通过在连接字符串中设置useLocalSessionState = true来解决此问题.

We solved this issue by just setting useLocalSessionState=true in the connection string.

下面的链接详细说明了Mysql5.6和Java连接器5.1.23中发生的ReadOnly相关更改的详细信息. http://dev.mysql.com/doc/relnotes/connector-j/zh-CN/news-5-1-23.html

The below link explain the details of ReadOnly related changes happened from Mysql5.6 and the java connector 5.1.23. http://dev.mysql.com/doc/relnotes/connector-j/en/news-5-1-23.html

这篇关于Java Hibernate对分离对象进行不必要的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆