奇怪的休眠缓存问题

时间:2008-10-07 17:52:00

标签: java hibernate spring

我们正在使用Hibernate 3.1和Spring MVC 2.0。当数据直接在数据库上更新(而不是在应用程序中)时,会出现问题。我们使用过滤器根据订单是打开还是关闭来过滤结果集合。如果我们更改要关闭的DB上的订单,过滤器将返回正确的列表,但是,对象的状态不会更改。

  • 我们没有启用二级或查询缓存。
  • 从数据库中检索集合是通过Hibernate的Session.createQuery。
  • 此外,我们有一个SessionFactory连线,并在整个应用程序中使用一个Session。

对象显示正确状态结果的唯一时间是服务器重新启动时 - 我们不希望定期执行此操作。

4 个答案:

答案 0 :(得分:3)

Session始终具有“第一级”缓存,因此如果您使用一个Session,那么您通过它读取的所有内容都将被缓存。 Hibernate将对数据库执行查询,但是当它构建对象时,它会检查Session缓存以避免构建新对象,因此数据库中更改的任何列都不会刷新。如果你关闭它并获得一个新的Session,它将在下一个查询中从数据库中读取完整的对象。

答案 1 :(得分:1)

当你有进程“背后”时,你真的不能指望Hibernate正确地管理其缓存对象的“脏”状态。如果您正在使用注释,我建议将状态(如果该字段的名称)标记为@Transient,以便Hibernate知道每次都必须从数据库中获取此值。

答案 2 :(得分:1)

您可能希望启用缓存并设置到期时间。 然后,一旦缓存过期并且有人请求,Hibernate将刷新数据库中的数据。

我在家庭项目中使用它,因为我偶尔会调整数据库。然后我等一会儿,刷新页面,看看我调整的数据。

看看Hibernate中的ehcache。

答案 3 :(得分:1)

您可以使用版本控制Hibernate Version。您的外部进程必须增加版本号(或时间戳)才能让Hibernate知道新版本可用。

这不一定是立即改变,但比容器重启更频繁(在我们的案例中每隔几分钟)。

它有一些缺点:

  • 您的应用程序可能会在旧数据上运行一段时间
  • 如果版本因批处理作业而增加,并且hibernate尝试保存更新的旧版本记录,则会产生异常
  • 共享数据库的扩展性会降低;经常检查可以降低成本。

我绝不是Hibernate专家,但它是可能的。