2014-06-21 114 views
2

我想澄清一下关于hibernate二级缓存的一些观点。需要澄清的是,HQL查询是否总会碰到数据库(至少是为了获得ID)。请问HQL查询使用Hibernate二级缓存

考虑,我们有实体

class Customer { 

    long id; // Primary key 

    String name; 

    set <Address> addressList; // One to many relationship 

} 

class Address{ 

    long id; // Primary key 

    String houseName; 

} 

的地址数据库表有外键参考客户(ID),以支持一对多的关系。

作为一个先决条件,我已经为Hibernate启用了2级缓存作为EHcache。只有实体和关联被设置为可缓存。查询缓存未启用。

我知道,如果我多次使用session.get()或session.load(),只有第一次调用将启动对数据库的查询,并且后续的将从第2级缓存中获取数据。

我的问题是

1)请问HQL会利用二级缓存。 在一个会话中,我执行一个HQL以使用主键(id)“从Customer c where c.id =?”).setParameter(1,1005)获取对象。

如果我在不同的会话中运行相同的HQL,Customer对象是从2级缓存中取出还是再次打到数据库。

2)考虑选择客户和关联地址的另一个HQL执行from Customer as c left join fetch c.addressList

如果我在不同的会话中运行相同的HQL,将关联的地址从二级缓存中取出,否则它将再次访问数据库。

+0

是的,HQL使用第二级缓存,但前提是您将'hibernate.query_cache'设置为true并在查询中使用'setCacheable(true)'。 –

回答

3

因为您还没有启用查询缓存,所以没有实体查询会碰到第二级缓存。因此,这两个查询和对数据库运行。

如果您希望这些查询使用第二级缓存,您可以启用查询缓存。查看this article了解关于此主题的更多信息。

+0

谢谢@VlanMihalcea。对于问题1,我相信hibernate将运行查询并获取与搜索条件匹配的所有表行的id。然后它将使用id加载对象。该对象可以根据可用性从级别2或从DB加载。奇怪的是,在这里,我只是通过ID进行搜索,但仍然需要再次访问数据库以获取相同的ID。 –

+1

通过id搜索是一种重写默认获取机制的方法,因此您可以显式声明新的获取计划,并且查询也可以在执行它之前触发flush,所以这就是为什么它不会简单地忽略所有返回来自第一级或第二级缓存的实体。 –

+0

请查找相似主题[link](http://stackoverflow.com/questions/8989584/does-hql-query-always-hit-database-and-get-results) –

相关问题