Java EhCache Hibernate二级缓存maxBytesLocalHeap慢速
我在Spring驱动的应用程序中使用Hibernate(4.2.15.Final)和EhCache(2.6.9)作为二级缓存,设置了一个非常标准的持久层 一切正常。但是,将条目放入二级缓存有时需要很长时间 我已经在显式Java EhCache Hibernate二级缓存maxBytesLocalHeap慢速,java,hibernate,caching,jpa,ehcache,Java,Hibernate,Caching,Jpa,Ehcache,我在Spring驱动的应用程序中使用Hibernate(4.2.15.Final)和EhCache(2.6.9)作为二级缓存,设置了一个非常标准的持久层 一切正常。但是,将条目放入二级缓存有时需要很长时间 我已经在显式ehcache.xml文件中配置了域模型类的缓存(我没有配置默认缓存): 在执行过程中发出以下警告 ObjectGraphWalker | The configured limit of 1,000 object references was reached while attem
ehcache.xml
文件中配置了域模型类的缓存(我没有配置默认缓存):
在执行过程中发出以下警告
ObjectGraphWalker | The configured limit of 1,000 object references was reached while attempting to calculate the size of the object graph. Severe performance degradation could occur if the sizing operation continues. [...]
AFAIKObjectGraphWalker
必须调整放入缓存的实体的大小,因为我使用maxBytesLocalHeap
配置了单缓存区域
我的域模型非常复杂,我知道我可以用@IgnoreSizeOf
注释限制图的遍历,但我不确定如何解决这个问题:
- 我是否必须忽略双向关联的一侧以避免循环
- 我是否必须显式忽略域模型类的临时成员
- 一般来说,当与Hibernate一起使用EhCache时,使用
明智吗?还是我应该选择maxBytesLocalHeap
,因为Hibernate为每个实体保留一个单独的缓存区域李>maxEntriesLocalHeap
[更新]:我发现,Hibernate不会缓存临时成员(请参阅),因此ehcache无论如何都不应将其视为临时成员。对吗 简短回答 事实证明,我遇到的问题是在我的模型中使用Joda时间实例(我用来映射Joda类型)的结果 Joda类型保留各种内部引用(包括对年表信息的引用,从而生成一个巨大的对象图),Ehcache的
SizeOfEngine
遍历这些引用,从而得到我最初的警告
我没有找到干净的方法来配置SizeOfEngine引擎以排除这些引用,但我想更干净的方法是强制Hibernate首先只将相关信息放入二级缓存(在我的例子中是LocalDateTimes
)
更新
Jadira在实现其自定义类型时的选择很差:请参见
更多详细信息
以下是关于我的OP的发现(使用Hibernate 4.2.15.Final、EhCache 2.6.9和UserType 3.2.0.GA):
首先,我对Hibernate如何在它的二级缓存中存储实体有一个误解。读了Lorimer关于很多事情的博客后,我觉得更有意义:
- 您不必担心双向关联(或循环图),因为Hibernate只会将关联的ID放入缓存中。即使它将对整个实体的引用放入缓存中(它没有这样做),EhCache的SizeOf引擎也会跟踪已经访问过的图形中的对象,并且不会将其大小调整两倍
- 同样,您不必担心临时字段,因为Hibernate不会将它们放入缓存
- 理论上,使用
配置应该不会有任何问题。当前,当您使用EhCache的SizeOf引擎无法正确测量的自定义用户类型时,会出现问题maxBytesLocalHeap
- 我知道这是个老问题。但它可能对某些人有用。
我得到了同样的警告。我花了很多时间来解决这个问题。
在我的例子中,EhCache不会忽略所有hibernate代理类。我的实体有一些字段具有惰性关联,在度量大小的过程中,EhCache遍历整个hibernate图
最后我发现并解决了它 我调查了这篇文章,发现我们的问题与Hibernate没有任何关系;事实上,ehcache 2.10.3和可能更早的版本都有一个预配置的过滤器,似乎是正确的(
ehcache-2.10.3.jar!/net/sf/ehcache/pool/builtin sizeof.filter
)。这篇文章很有趣,因为我找到了一种方法,通过在net.sf.ehcache.pool
上启用调试日志并设置static{System.setProperty(“net.sf.ehcache.sizeof.verboseDebugLogging”,“true”);}
来查找添加到缓存中的条目。原来是一个由Spring@Cacheable
注释的服务返回了一个ResourceBundle
DefaultSizeOfEngine | using Agent sizeof engine
ObjectGraphWalker | The configured limit of 1,000 object references was reached while attempting to calculate the size of the object graph. Severe performance degradation could occur if the sizing operation continues. [...]