java阻止Hibernate会话刷新/存储无效的脏实体
我想知道应该采取什么方法来防止Hibernate 4.3.4(使用Spring和Hibernate Vaidator)刷新脏的实体。 在我的代码中,我使用了Hibernate Validator(实例本身中的一个.validate()方法)的手动实现,它在保存实体之前被调用。validate()方法返回错误列表(如果发现),否则返回会话。调用update()存储实体,然后提交事务
这是可行的,但当实例本身被操纵(在实体中设置了POST/request参数)时,实体和相应的Hibernate会话被标记为“脏”,实体与下一个会话一起存储。刷新()
在我的情况下,我希望对可能存储的实体有明确的控制,并防止任何脏实体被存储,我将如何实现这一点
编辑:
我知道我可以通过逐出一个实体(或通过合并清除并重新引入一个实体)来手动调节这一点,但这不是我的目标。我不需要手动调节持久性,而是希望有一种补偿情况,即没有显式保存且没有显式提交事务的实体不会存储到数据库中(例如,通过拦截器?)
# 1 楼答案
如果修改实体并明确希望它们不被刷新,可以在修改之前分离它们。分离的实体将不再由持久性上下文管理
Hibernate API:
^{}
JPA:
^{}
编辑:如果要分离所有实体并只管理其中的一部分,可以先清除持久性上下文,然后合并需要管理的实体:
Hibernate API:
JPA:
编辑2事务提交时刷新对托管实体的所有更改。我不知道JPA或Hibernate的任何功能可以关闭这种行为。因此,除了分离部分或所有实体,您还有一些其他选择,但没有一个正是您想要的:
获取事务外部的实体,以便立即分离它们。这似乎与您想要的最接近——管理的更改没有麻烦,只有显式合并才能保存实体,并且您需要更少地处理持久性API。但是,您仍然需要打开一个会话来合并您确实希望保存更改的实体
在查询中使用
NEW
操作符将查询结果映射到DTO/POJO(总是分离的)。这种方法的优点是将持久性映射与应用程序分离。然而,引入一系列新类可能不值得,而且在整个应用程序中不一致地这样做会增加概念上的复杂性在事务内部工作,但回滚而不是提交。您将无法保存任何内容,这是一种防止更改与数据库同步的粗糙方法。不幸的是,最终必须提交或回滚事务
创建实体的深度副本以进行更改。坦白地说,这对我来说也没有多大意义,只是为了完整起见才添加它
EDIT 3虽然JPA规范没有指定,但Hibernate和Eclipselink都允许将单个查询中的事务甚至结果集标记为只读。这可能对你有用,就像
当涉及到人际关系时,变化会变得更加复杂。请参阅this documentation for Hibernate或this one for Eclipselink