2009-08-25 140 views
13

我有一个Hibernate域对象,它被应用程序的不同部分加载。有时延迟加载每个关联和其他的更有利于在一个连接中加载整个事物。作为一个希望愉快的妥协,我发现:休眠:batch_size?二级缓存?

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

hibernate.default_batch_fetch_size

使用批量抓取,Hibernate可以加载 如果一个访问代理其他未代理。批量抓取是对懒惰选择抓取策略的优化。

我也参见:

hibernate.jdbc.fetch_size

非零值,指定JDBC抓取大小(调用Statement.setFetchSize())。

那么Hibernate是否足够聪明,可以在进行批量抓取时查看二级缓存?也就是说,是否有初始调用访问关联,然后接下来的X个调用是否会触发缓存?通过这种方式,我可以获得我想要的延迟加载,但也经常为更大容量的事务启动缓存。

如果集合的全部内容已经包含在缓存中,它是否仍然执行对集合访问的提取查询?

谢谢。

+0

现在,我也想知道答案。 – Zoidberg 2009-08-25 16:58:11

+1

标记我的问题:-) – davidemm 2009-08-25 17:20:56

回答

6

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

集合是否已初始化?

  • 不是吗?执行批量提取(通过批量提取获取的项目放在缓存中)
  • 是吗?在缓存中查找特定项目,如果它不在那里进行批量提取。

因此,如果您正在寻找的集合中的项目在缓存中找到,那么批量获取不会发生。如果在二级缓存中未找到该项目,则会发生批量提取,但是会批量提取批量项目,而不管批量项目是否在缓存中。


-----例1 -----

优点:

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

  • collection.getItem(0) - No cache |批量取3项
  • 集合。的getItem(1) - 通过加载批量取
  • collection.getItem(2) - 通过加载批量取

现在,别的地方,后来时间:

  • 集合。的getItem(0) - 高速缓存命中
  • collection.getItem(1) - 高速缓存命中
  • collection.getItem(2) - 高速缓存命中

-----实施例2 -----

缺点:

(在收集三个项目 - 3批量大小)

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

  • collection.getItem(0) - 不在缓存所以做批3(SELECT *凡在(,ID)???)
  • collection.getItem(1) - 在缓存中已经(被替换反正通过批量提取)
  • collection.getItem(2) - 在缓存中已经(被替换反正批量提取)

所以在这里下车的交易是,你有较少的SQL调用由于批处理,但你会错过更多的缓存。有一张票可以在第二级缓存中查看批处理,然后发送到数据库。

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

投上一票!