Hibernate:batch_size?二级缓存?

时间:2009-08-25 16:55:07

标签: hibernate second-level-cache fetching-strategy

我有一个Hibernate域对象,它由应用程序的不同部分加载。有时延迟加载每个关联和其他关联是有利的,最好在一个连接中加载整个事物。作为一个充满希望的妥协,我发现:

使用批量提取,如果访问一个代理,Hibernate可以加载几个未初始化的代理。批量提取是惰性选择提取策略的优化。

hibernate.default_batch_fetch_size

  

使用批量提取,Hibernate可以加载几个未初始化的代理   如果访问一个代理。批量提取是一种优化   懒惰选择提取策略。

我也看到了:

hibernate.jdbc.fetch_size

  

非零值确定JDBC提取大小(调用Statement.setFetchSize())。

Hibernate是否足够聪明,可以在进行批量提取时查看二级缓存?即,一次获取对该关联的初始调用,然后下一次X调用是否到达缓存?这样我就可以拥有我想要的延迟加载,但也经常在缓存中进行更多批量交易。

如果集合的整个内容已经包含在缓存中,它是否仍会在访问集合时执行获取查询?

感谢。

1 个答案:

答案 0 :(得分:6)

我今天做了很多研究,并且能够对我自己的问题做出回应。我正在查看Hibernate代码,流程如下所示:

集合是否已初始化?

  • 否?批量提取(通过批量提取获得的项目放在缓存中)
  • 是?查看特定项目的缓存,如果没有批量获取。

因此,如果集合中的项目正在缓存中找到IS FOUND,那么批量获取不会发生。如果在二级缓存中找不到该项,则会发生批量提取,但是它将执行批处理项的提取,无论批处理项是否在缓存中。


-----示例1 -----

善良:

(集合中的三个项目 - 批量大小为3) 第一次去:

  • collection.getItem(0) - 没有缓存|批量获取3项
  • collection.getItem(1) - 由batch-fetch加载
  • collection.getItem(2) - 由batch-fetch加载

现在,在其他地方,以后的时间:

  • collection.getItem(0) - 缓存命中
  • collection.getItem(1) - Cache Hit
  • collection.getItem(2) - Cache Hit

-----例2 -----

坏消息:

(集合中的三个项目 - 批量大小为3)

在这种情况下,索引0处的项目已从缓存中删除,因为缓存可能已满并且项目已被删除,或者项目已过时或闲置。

  • collection.getItem(0) - 不在缓存中所以批量为3(选择*其中id为(?,?,?))
  • collection.getItem(1) - 已在缓存中(无论如何都被批量取指)
  • collection.getItem(2) - 已在缓存中(无论如何都被批量替换)

因此,这里的权衡是由于批处理您将减少SQL调用,但是您会更频繁地错过缓存。在打开数据库之前,有一个打开的票证可以在二级缓存中进行批处理查看。

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775

投票!