当前位置: 动力学知识库 > 问答 > 编程问答 >

caching - hibernate query cache has different number of sql without L2 cache

问题描述:

I am using hibernate 4.3.10 , enable query cache, without L2 cache,

tested following code(call it Part1) :

Session s1 = sessionFactory.openSession();

List<StudentQuery> students = s1.createQuery("from StudentQuery").setCacheable(true).list();

s1.close();

Session s2 = sessionFactory.openSession();

List<StudentQuery> stus = s2.createQuery("from StudentQuery").setCacheable(true).list();

sessionFactory.close();

following is the output :

Hibernate: select studentque0_.id as id1_5_, studentque0_.age as age2_5_, studentque0_.name as name3_5_ from student studentque0_

Hibernate: select studentque0_.id as id1_5_0_, studentque0_.age as age2_5_0_, studentque0_.name as name3_5_0_ from student studentque0_ where studentque0_.id=?

Hibernate: select studentque0_.id as id1_5_0_, studentque0_.age as age2_5_0_, studentque0_.name as name3_5_0_ from student studentque0_ where studentque0_.id=?

Hibernate: select studentque0_.id as id1_5_0_, studentque0_.age as age2_5_0_, studentque0_.name as name3_5_0_ from student studentque0_ where studentque0_.id=?

Hibernate: select studentque0_.id as id1_5_0_, studentque0_.age as age2_5_0_, studentque0_.name as name3_5_0_ from student studentque0_ where studentque0_.id=?

Hibernate: select studentque0_.id as id1_5_0_, studentque0_.age as age2_5_0_, studentque0_.name as name3_5_0_ from student studentque0_ where studentque0_.id=?

Hibernate: select studentque0_.id as id1_5_0_, studentque0_.age as age2_5_0_, studentque0_.name as name3_5_0_ from student studentque0_ where studentque0_.id=?

However, for next code(call it Part2) :

Session s1 = sessionFactory.openSession();

List<StudentQuery> students = s1.createQuery("from StudentQuery").setCacheable(true).list();

List<StudentQuery> students2 = s1.createQuery("from StudentQuery").setCacheable(true).list();

sessionFactory.close();

the output is :

Hibernate: select studentque0_.id as id1_5_, studentque0_.age as age2_5_, studentque0_.name as name3_5_ from student studentque0_

Why the output are different? There are 7 hql statements in Part1 while there is only one in Part2.

The entity is(I commented the @Cache to disable L2 cache) :

@Entity

@Table(name="student")

//@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,region="student")

public class StudentQuery {

.....

}

the hibernate.cfg.xml looks like :

<hibernate-configuration>

<session-factory>

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="connection.url">jdbc:mysql://localhost/test</property>

<property name="connection.username">test</property>

<property name="connection.password">abc</property>

<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="connection.pool_size">1</property>

<property name="current_session_context_class">thread</property>

<property name="hibernate.cache.region.factory_class">

org.hibernate.cache.ehcache.EhCacheRegionFactory

</property>

<property name="hibernate.cache.use_second_level_cache">true</property>

<property name="net.sf.ehcache.configurationResourceName">

resources/ehcache.xml

</property>

<property name="show_sql">true</property>

<property name="hbm2ddl.auto">update</property>

<property name="hibernate.cache.use_query_cache">true</property>

<mapping resource="resources/event.hbm.xml"/>

<mapping resource="resources/person.hbm.xml"/>

<mapping class="com.my.hibernate.basic.Student" />

<mapping class="com.my.hibernate.basic.StudentL2" />

<mapping class="com.my.hibernate.basic.StudentQuery" />

</session-factory>

</hibernate-configuration>

网友答案:

I assume you have the query cache enabled.

In the first case, you open a first session and execute a query for the first time. The query cache is populated with the IDs of the students returned by the query. The L2 cache is disabled so the students are not stored in it. Then you open a second session and execute the same query. The IDs are retrieved from the query cache without touching the database. But then Hibernate gets the students from the session, one by one. Since the session is new, they're not in the session, and they're not in the L2 cache either. So it has to hit the database for every student.

In the second case, you're doing everything from the same session. So the query is first executed andthe IDs are stored in the query cache. Then you execute the same query. The IDs are found in the query cache, and Hibernate gets every student from the session. They are already there, since the first query populated the session.

Morale of the story: enabling the query cache but not the L2 cache is a waste of resources: you'll end up with much more queries because you'll force Hibernate to get the entities by ID from the database, one by one. Don't do that.

分享给朋友:
您可能感兴趣的文章:
随机阅读: