【问题标题】:Entity not getting saved after transaction commit事务提交后实体未保存
【发布时间】:2012-12-30 16:54:30
【问题描述】:

一些背景知识,我在我的 Web 应用程序中使用 JPA/Hibernaate/Spring 我还使用 org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter 和扩展的持久性上下文来处理我的实体。

问题:

  1. 用户点击实体的编辑链接

  2. 使用 find 方法从数据库加载实体,并将实体存储在会话中

  3. 用户对实体进行更改并点击保存

  4. 用户更改反映在存储在会话中的实体上(在控制器中)

  5. 实体被发送到服务类中的方法(使用@Transactional 注释)

  6. 在服务类中不会对实体(或任何其他实体)进行任何更改(它会做一些其他与持久性无关的事情)

  7. 服务方法完成后没有任何更改刷新到数据库!!!?

注意:服务类是一个spring组件,我调试了为它创建的spring代理,当调用@Transactional注释的服务方法时,我看到spring在服务方法调用之前创建了一个新事务,我也看到它提交了事务成功地。据我了解,即使对实体的更改没有发生在事务边界中,它仍然应该刷新到数据库中。为什么没有刷新更改?!

【问题讨论】:

  • 尝试在调试级别查看 Hibernate 的日志,您应该会在那里找到一些信息

标签: java jpa


【解决方案1】:

对于要刷新的实体,必须对其进行管理。该实体可能已分离。

我可以想到在这种情况下它被分离的两个可能原因:

  1. 即使对于扩展的持久性上下文,也会创建和关闭实体管理器。也许您在每次调用服务器时打开和关闭它?然后,因为您尝试将实体保存在与创建该实体的服务器不同的调用中,所以实体管理器是一个新的,因此该实体不受管理。

  2. 实体在对服务器的这些调用之间进行序列化。当一个实体被序列化时,它就变得分离了。这很容易发生,因为服务器经常在调用之间将会话数据写入磁盘。

【讨论】:

  • 第 1 点是我的情况,因为 OpenEntityManagerInViewFilter 关闭了用于在每个请求结束时加载我的实体的实体管理器,实体变得分离并且需要合并才能进行更改在任何以下请求中对他们生效。我想知道在 EJB 的有状态会话 bean 中使用容器管理的实体管理器(具有扩展的持久性上下文)时是否也是这种情况?
【解决方案2】:

如果用户更改是在您的服务层之外进行的,则更改不会自动持久化,除非您在服务层内部调用persist:

entityManager.persist()

你可以看到here为什么要使用persist而不是merge。

希望对您有所帮助。

【讨论】:

  • 由于实体被分离,无法使用persist方法。
  • @MD.Unicorn 正如我所说,我使用扩展的持久性上下文,因此实体没有分离。
  • @Zaroual 谢谢,您是否可以提供任何参考来支持您的回答并解释这种情况?因为很明显我可以通过使用 API 来解决问题,但我对理解问题和使用最佳实践更感兴趣。
  • 我没有说你必须在你的服务层之外调用persist,很明显这不起作用,因为实体是分离的,如果你尝试这个你会得到一个异常:分离的实体传递给持久化或之类的。所以,在你的服务层中调用 persist 方法。
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多