有些背景,我在我的Web应用程序中使用JPA / Hibernaate / Spring我还使用org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter和扩展的持久化上下文来处理我的实体。
问题:
用户点击实体的修改链接
使用查找方法从数据库加载实体,实体存储在会话中
用户对实体进行更改并点击保存
用户更改会反映在会话中(存储在控制器中)的实体
实体被发送到服务类中的方法(使用@Transactional注释)
在服务类中没有对实体(或任何其他实体)进行任何更改(它会执行其他一些与持久性相关的事情)
服务方法完成后,没有更改刷新到数据库!!!?
注意:服务类是一个spring组件,我调试了为它创建的spring代理,当调用@Transactional注释的服务方法时,我看到spring在服务方法调用之前创建了一个新事务,我也看到它提交了事务成功。根据我的理解,即使实体的更改没有发生在事务边界中,它仍然应该刷新到数据库。为什么变化没有被冲洗?!
答案 0 :(得分:1)
对于要刷新的实体,必须对其进行管理。该实体可能已经分离。
在这种情况下,我可以想到两个可能的原因:
即使对于扩展的持久性上下文,也会创建并关闭实体管理器。也许你在每次调用服务器时打开和关闭它?然后,因为您尝试将实体保存在与创建该实体的服务器不同的服务器中,所以实体管理器是新的实体管理器,因此不管理该实体。
实体在这些对服务器的调用之间进行序列化。当一个实体被序列化时,它就会变得分离。这很容易发生,因为服务器经常在调用之间将会话数据写入磁盘。
答案 1 :(得分:-1)
如果用户更改是在服务层之外进行的,则更改将不会自动保留,除非您在服务层内调用persist:
entityManager.persist()
你可以看到here为什么要使用persist over merge。
我希望这很有帮助。