在JPA中,如果我们调用EntityTransaction.commit(),是否自动调用EntityManager.flush()?或者我们应该都叫它们?有什么区别?因为我在使用JPA时遇到了问题,当我向数据库中插入实体时,我调用了persist()。在数据库中,数据已插入(可获取),但该数据未显示在我的应用程序中(我使用findAll()获取它)。在另一个实体上,它出现了。是否有什么我不知道?我使用是标准的SpringCRUD、JPAresource_local和postgresql.对不起我的英语,提前感谢
3条答案
按热度按时间vmjh9lq91#
如果我们调用EntityTransaction.commit(),它是否会自动调用EntityManager.flush()?
是的
有什么区别呢?
在flush()中,数据的更改在遇到flush后会反映在数据库中,但它仍然在事务中。flush()必须包含在事务上下文中,除非需要(在极少数情况下),否则您不必显式地执行此操作,此时EntityTransaction.commit()会为您执行此操作。
Source
2ul0zpep2#
em.flush()-它将实体立即保存到数据库中,以便在事务中进一步使用,并且可以回滚。
em.getTransaction().commit-它标记事务的结束,并将事务中的所有更改保存到数据库中,并且不能回滚。
参考https://prismoskills.appspot.com/lessons/Hibernate/Chapter_14_-_Flush_vs_Commit.jsp
y1aodyip3#
如果您的实体中有一个@Version注解列,并调用entityManager.flush(),那么您将(立即!)获得一个OptimisticLockException,或者数据库将锁定此行(或表)。在后一种情况下,您仍然可以调用setRollbackOnly(),并且锁定稍后将被释放,而不需要更改DB。
或者从另一个Angular 看,使用flush()可以在数据库行上创建一个(悲观)锁。其他人仍然会看到旧的条目,但如果他们试图更新,他们将被阻止,直到锁被释放。
对于CMT(容器管理的事务)也是如此。您可以在服务方法中调用flush()(甚至多次)并立即处理OptimisticLockException(s),而不是等待服务方法完成并执行CMT提交的时刻。