Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 事务提交后未保存实体_Java_Jpa - Fatal编程技术网

Java 事务提交后未保存实体

Java 事务提交后未保存实体,java,jpa,Java,Jpa,在某些背景下,我在我的web应用程序中使用JPA/Hibernate/Spring,我还使用org.springframework.orm.JPA.support.OpenEntityManagerInViewFilter和扩展的持久性上下文来处理我的实体 问题是: 用户单击实体的编辑链接 使用find方法从数据库加载实体,实体存储在会话中 用户对实体进行更改并点击保存 用户更改反映在会话中存储的实体上(在控制器中) 实体被发送到服务类中的方法(用@Transactional注释) 服务类中没有

在某些背景下,我在我的web应用程序中使用JPA/Hibernate/Spring,我还使用org.springframework.orm.JPA.support.OpenEntityManagerInViewFilter和扩展的持久性上下文来处理我的实体

问题是:

  • 用户单击实体的编辑链接

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

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

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

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

  • 服务类中没有对实体(或任何其他实体)进行任何更改(它执行一些其他与持久性无关的操作)

  • 完成服务方法后,不会刷新对数据库的任何更改


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

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

    entityManager.persist()
    
    您可以看到为什么要使用persistenovermerge


    我希望这会有所帮助。

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

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

  • 即使对于扩展持久性上下文,也会创建并关闭实体管理器。也许您在每次调用服务器时都会打开和关闭它?然后,由于您试图在对创建实体的服务器的不同调用中保存实体,因此实体管理器是新的,因此该实体不受管理

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


  • 尝试在Hibernate的调试级别查看日志,您应该会在其中找到一些信息,因为实体已分离,无法使用
    persist
    方法。@MD.Unicorn正如我所说,我使用扩展持久性上下文,因此实体未分离。@Zaroual谢谢,您是否可以提供任何参考来支持您的答案并解释此案例?因为很明显,我可以通过使用API来解决这个问题,但我更感兴趣的是理解这个问题并使用最佳实践。我没有说你必须在服务层之外调用persist,很明显,这将不起作用,因为实体是分离的,如果您尝试这样做,您将得到一个异常:分离的实体传递给持久化或类似的东西。因此,在您的服务层内调用persist方法。在我的案例中,第1点就是发生的情况,因为OpenEntityManagerViewFilter在每个请求结束时关闭了用于加载实体的entitymanager,所以实体会分离,需要合并,以便在任何后续请求中对它们所做的更改生效。我想知道在EJB中的有状态会话bean中使用容器管理的实体管理器(具有扩展的持久性上下文)时是否也是这样?