Java 实体管理器操作命令

Java 实体管理器操作命令,java,hibernate,jpa,transactions,ejb,Java,Hibernate,Jpa,Transactions,Ejb,最近我遇到了一个有趣的问题。我在项目中使用JPA+Hibernate+EJB。问题涉及保存和删除同一事务中的实体。使用的数据库表在两列上定义了唯一约束 我要做的是删除实体调用 entityManager.remove(); 然后,使用与唯一约束中使用的列关联的两个特性中的相同值添加新实体,但使用以下方法添加其他特性中的不同值: entityManager.persist(); 这两个操作在单个事务中执行,并按照上述顺序执行。先拆后加。然而,由于违反了唯一约束,操作似乎是以相反的顺序执行的。看

最近我遇到了一个有趣的问题。我在项目中使用JPA+Hibernate+EJB。问题涉及保存和删除同一事务中的实体。使用的数据库表在两列上定义了唯一约束

我要做的是删除实体调用

entityManager.remove();
然后,使用与唯一约束中使用的列关联的两个特性中的相同值添加新实体,但使用以下方法添加其他特性中的不同值:

entityManager.persist();
这两个操作在单个事务中执行,并按照上述顺序执行。先拆后加。然而,由于违反了唯一约束,操作似乎是以相反的顺序执行的。看起来新实体是在删除前一个实体之前添加的

显然,我可以打电话

entityManager.flush()
在删除后,则不违反约束。但是,在这种情况下,数据会在提交整个事务之前保存到数据库中。这不是一个令人满意的行为。如果刷新后出现任何错误,事务将被标记为回滚,则该实体仍将被删除

我认为操作顺序与添加到事务中的操作顺序相同。从我的例子来看,事实并非如此

是否有任何方法可以在删除后不刷新或提交事务的情况下解决问题

多谢各位

显然,我可以调用
entityManager.flush()

事实上,你必须叫它

但是,在这种情况下,数据会在 整个事务提交

这是错误的:数据被同步到数据库,但事务仍然没有提交,除非您手动提交它并控制数据库。如果您没有在EJB中配置任何东西,并且您的持久化单元是JTA(请参阅),那么只有在方法从EJB层返回后,才会提交事务

我认为操作顺序与添加到的操作顺序相同 交易。从我的例子来看,事实并非如此

不,JPA规范并不强制实现这样做。这就是为什么会有一个
flush()
操作

有没有办法在不刷新或提交文件的情况下解决问题 删除后的交易


是的,正如我说的,使用
flush()
。还要确保使用事务性数据库引擎(例如MySql中的MyIsam不支持事务)。

我确实遇到了同样的问题,我这样解决了它:
EntityManager.getTransaction().begin()
EntityManager.remove()
EntityManager.persist()
EntityManager.getTransaction().commit()

如果出现任何问题,请将删除和持久化操作分为两个不同的事务

不建议使用Ossama Nasser建议的解决方案,因为如果使用不同的事务,则在第二个或下一个事务中某些内容失败时,将使回滚到初始状态的可能性无效


entityManager.flush()是正确的解决方案。

我使用JTA和事务数据库(Oracle),所以一切都应该正常。精彩的解释安德烈。关于事务提交的问题,我错了。现在很清楚了。我认为这个问题和答案也会对其他人有用。谢谢。但是,我需要在一个事务中执行这两个操作。这不应该作为新答案添加,而是作为对您所指答案的注释。