2013-03-01 72 views
0

我们使用以下属性启用有关休眠二级缓存:Hibernate的二级缓存延迟集合大小

hibernateProperties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); 
hibernateProperties.setProperty("hibernate.cache.use_query_cache", Boolean.TRUE.toString()); 
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", Boolean.TRUE.toString()); 
hibernateProperties.setProperty("hibernate.cache.use_structured_entries", Boolean.TRUE.toString());  
hibernateProperties.setProperty("hibernate.cache.generate_statistics", Boolean.TRUE.toString()); 

而且使用缓存标签标记我们的实体:

@Entity 
@Indexed 
@Table(name = "item") 
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) 
public class Item implements Serializable { 

这个实体有一个懒惰的收集与懒惰收集选项额外:

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) 
@ManyToMany(fetch = FetchType.LAZY, targetEntity = User.class, mappedBy = "likes") 
@LazyCollection(LazyCollectionOption.EXTRA) 
private List<User> users; 

这似乎运作良好,我没有看到任何数据库查询中的数据已经被缓存之后,但是我们确实看到有一个日志调用来

select count(user_id) from user_items where item_id =? 

有没有什么办法让冬眠缓存的大小懒惰的收集,所以当我们做users.size()时它不需要击中数据库?


我已更改为CacheConcurrencyStrategy.READ_WRITE并查看相同的行为。

在第一个请求中,我看到查询选择实体和查询以查找集合的大小。我看到日志消息说实体正在被缓存。

在随后的请求中,没有调用来加载实体,但仍然有调用来查找集合的大小。

回答

0

当数据被缓存时,您永远不会看到数据库查询。并且您在说有选择查询的连续日志。 Ehcache不提供事务性缓存。 你在说它是在工作。 兄弟它不工作,你只是有数据库调用和日志相同。 检查Ehcache文档,因为它不支持TRANSACTIONAL缓存

+0

“Ehcache文档,因为它不支持TRANSACTIONAL缓存” - 这是什么意思,你认为事务缓存是什么? – NimChimpsky 2013-03-01 10:43:29

+0

我已更改为CacheConcurrencyStrategy.READ_WRITE并查看相同的行为。在第一个请求中,我看到查询以选择实体和查询来查找集合的大小。我看到日志消息说实体正在被缓存。在随后的请求中,没有调用来加载实体,但仍然有调用来查找集合的大小。 – Chris 2013-03-01 11:12:41

0

用户列表是一个延迟加载的集合。 在Lazy loaded collection中,您不会有任何数据。 无论何时你想要访问Lazy加载的集合,或者你想确定延迟加载的集合的大小,它都必须有关于其中的数据的信息,比如有多少个元素。 为此,它将从数据库获取该数据,并因此每次都会生成数据库查询。 我检查了这两个列表作为最高层和其他一些对象。 这表明当List不是顶级对象时,它将被懒惰地初始化。 因此,无论何时想要获取有关集合的信息或从集合中获取信息,都将生成数据库查询。