我正在调用 SLSB 方法,该方法的事务由容器控制。 在方法中,我尝试删除实体并创建新实体
List<FactPlan> factPlans = factPlanFacadeLocal.findAll();
for (FactPlan factPlan : factPlans) {
factPlanFacadeLocal.remove(factPlan);
}
FactPlan factPlan = new FactPlan(12264L, 12088L);
factPlanFacadeLocal.create(factPlan);
我有以下异常
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "pkfact_plan"
Detail: Key (fact_id, plan_id)=(12264, 12088) already exists.
我做错了什么?
UPD:JPA 实现是 EclipseLink
最佳答案
编辑: 我说你需要提交是错误的,在删除操作之后刷新就足够了,以确保不违反数据库约束。
发生了什么(EclipseLink 也完全相同):
Hibernate 仅查看事务持久性上下文内内存中发生的情况,如果不刷新,它无法抢先验证数据库约束(在本例中为主键)。 虽然 Hibernate 完全知道您已经删除了具有相同 ID 的项目(因为这一切都发生在同一个持久性上下文中),但数据库在刷新之前看不到您的任何更改。
现在您可能会想,为什么在事务结束时、提交之前让刷新自动发生还不够?当然,数据库操作的顺序将与 JPA 操作一致,并且数据库将在插入之前看到行删除。好吧,它不会,Hibernate 正在改变你的操作顺序,它把所有插入放在删除之前,打破了数据库约束:http://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/event/def/AbstractFlushingEventListener.html#performExecutions%28org.hibernate.event.EventSource%29
关于java - EJB事务误解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668724/