繁体   English   中英

防止Hibernate会话刷新/存储无效的脏实体

[英]Prevent Hibernate session from flushing/ storing invalid dirty entities

我想知道采取哪种方法来防止Hibernate 4.3.4(使用Spring和Hibernate Vaidator)来清除脏实体。 在我的代码中,我使用Hibernate Validator的手动实现(实例本身中的.validate()方法),在保存实体之前调用它。 validate()方法返回错误列表(如果找到),否则调用Session.update()来存储实体,然后提交事务。

这是有效的,但是当操作实例本身(在实体中设置发布/请求参数)时,实体和相应的Hibernate会话被标记为“脏”,并且实体与下一个Session.flush()一起存储。

在我的情况下,我想明确控制可能存储的实体并防止存储任何脏实体,我将如何实现这一目标?

编辑:

我知道我可以通过驱逐实体(或通过合并清算并重新引入实体)来手动调节这一点,但这不是我的目标。 我不想手动调节持久性,而是希望有一个偏移情况,即没有明确保存的实体以及未明确提交事务的实体将不会存储到数据库中(例如通过拦截器?)。

如果修改实体并明确要求不刷新它们,则可以在修改之前将它们分离。 分离的实体将不再由持久性上下文管理。

Hibernate API:

session.evict(myEntity)

JPA:

entityManager.detach(myEntity)

编辑 :如果要分离所有实体和管理只是其中的一部分,你可以先清除持久化上下文,然后合并需要管理的的entites:

Hibernate API:

session.clear();
managedEntity = session.merge(detachedEntity);

JPA:

entityManager.clear();
managedEntity = entityManager.merge(detachedEntity);

编辑2管理实体的所有更改都在事务提交时刷新。 我不知道JPA或Hibernate的任何功能可以关闭此行为。 因此,除了分离一些或所有实体之外,您还有其他一些选择,但没有一个是您正在寻找的:

  • 获取事务外的实体,因此它们会立即分离。 这似乎最接近你想要的 - 没有管理变更的麻烦,只有显式合并会保存一个实体,你将不得不减少持久性API。 但是,您仍然需要打开一个会话来合并您想要保存的实体和更改。

  • 使用查询中的NEW运算符将查询结果映射到DTO / POJO(始终分离)。 此方法具有将持久性映射与应用程序分离的优点。 然而,引入一堆新类可能不值得,并且在整个应用程序中不一致地添加它会增加概念上的复杂性。

  • 在事务中工作,但回滚而不是提交。 您将无法保存任何内容,这是防止更改与数据库同步的粗略方法。 不幸的是,您必须最终提交或回滚事务。

  • 创建实体的深层副本以更改它们。 坦率地说,这对我来说没有多大意义,只是为了完整而添加它。

编辑3虽然JPA规范没有规定,但Hibernate和Eclipselink都允许将单个查询中的事务或结果集标记为只读。 这可能对你有用,因为

当持久对象是只读的时,Hibernate不会检查简单属性

在谈到人际关系时,改变冲洗会变得更加复杂。 有关Hibernate的信息,请参阅此文档,或者参考Eclipselink的 此文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM