首页 > 解决方案 > 随着时间的推移,休眠速度变慢

问题描述

我的项目广泛使用 Hibernate 从 Postgresql 检索数据对象(我们使用的是 Hibernate 4.2.15 和 Postgresql 10.1-3)。代码如下所示:

public void hibernateSlowdown() {
    BigObject bigObject = new BigObject();
    for (int i=0 ; i<nObjects ; i++) {
        Target target = targetCrud.retrieve(i); // targetCrud has the Hibernate calls
        BigObject.target = target; 
        ...
        CustomSerializer.serialize(bigObject);
    }
}

日志记录显示,由于代码运行了非常多的迭代(大约 10,000 次),因此每次迭代所用的时间都比上一次要长。我确信这个问题与 Hibernate 缓存有关,原因如下:

  1. 通过大量的日志记录,很明显,循环中唯一在每次迭代中花费较长时间的部分是 targetCrud.retrieve(i) 调用。
  2. 当我向会话 clear() 方法添加蛮力调用时,性能显着提高,特别是不再随着时间的推移而变慢(或者更确切地说,在 clear() 调用之前它会变慢,然后再次加速)。

我曾希望使用 evict() 方法从 Hibernate 缓存中删除 Target 对象会给我类似的结果,但是 - 没有骰子,通过积极的努力驱逐所有 Target 对象,执行仍然会随着时间的推移而减慢与上述方法相同。

一个问题是 Target 类是嵌入式对象中的一种嵌入式对象,一些对象具有 FetchType 或 Cascade 注释,而另一些则没有,特别是 Target 具有嵌入式 Aperture 对象,而 Aperture 对象又具有父 Target 对象作为一个成员(所以 target.aperture.target = target)。

关于如何在不清除缓存的蛮力的情况下解决性能的任何建议?或者我怎样才能使 evict() 调用与缓存清除相当?关于获取类型、级联等,我需要了解什么,以确保具有多层嵌入对象的对象真正从缓存中删除?或者 Hibernate 缓存的工作方式是否有更基本的东西,这意味着驱逐不会解决我的问题,我将不得不忍受缓存清除?谢谢!

标签: javahibernate

解决方案


推荐阅读