如何强制 Hibernate 在其实体之一发生更改时不将更改传播到数据库
Posted
技术标签:
【中文标题】如何强制 Hibernate 在其实体之一发生更改时不将更改传播到数据库【英文标题】:How to force Hibernate not to propagate changes to database on change of one of its entities 【发布时间】:2012-12-15 15:01:54 【问题描述】:Hibernate 对一些事情非常有用。但是一件微不足道的事情却没有引起人们的注意。我想提供一种在“管理面板”中修改数据库条目的方法。更具体地说,我希望有一个能够修改产品、属性、图像、价格等的视图。因此,我通过例如会话加载要修改的产品的编辑视图.get(Product.class, id)。然后我使用它的属性、修改名称、设置价格、加载图像并做任何我想做的事情。但最终用户必须决定是保存更改还是丢弃它们。保存部分很容易 - 在服务层中调用 session.save 事务,但丢弃似乎是一个更难的问题,因为任何后续会话刷新都会将产品中取消的更改传播到数据库。
所以,我的问题是如何建立这样的方案。最好的选择是什么?我个人看到以下解决方案:
-
使用级联或调用 session.evict() 或
使用一些复制副本/DTO 并在保存操作时合并或
处理客户端上的所有更改,然后在保存时重新填充休眠实体。
【问题讨论】:
4.回滚事务。 您使用有状态还是无状态的服务器端技术?或者您甚至在谈论富客户端? 【参考方案1】:实际上,由于对休眠持久性生命周期的误解,我搞砸了基本的休眠功能。
因此,采用的典型方法之一是拆分 (1) 通过调用 dao.load(key)
方法加载实体并通过关闭关联的会话将其与会话分离,为用户提供处理它的时间,(2) 修改用户在表示层中分离实体,(3) 稍后将分离的对象重新附加到新会话,使其再次持久化,如有必要,通过合并它,调用dao.merge(object)
。当然,可以使用 DTO 来不干扰不同的程序层。
另一种明智的方法是在一个会话或事务中处理持久对象,在这种情况下,可以通过从会话中驱逐对象session.evict()
或回滚整个事务来简单地取消更改, transaction.rollback()
.
如果像我这样的人遇到这样的误解,我的参考列表将是:
-
Hibernate documentation on object states;
Hibernate documentation on persistence contexts 或
A good hibernate review presentation on slidreshare。
【讨论】:
以上是关于如何强制 Hibernate 在其实体之一发生更改时不将更改传播到数据库的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate @Where 未在 @MappedSuperClass 实体中强制执行