java - EntityManager.remove 和 EntityManager.persist 上的 JPA 重复条目错误

标签 java spring hibernate jpa entitymanager

我正在使用 JPA 的 Hibernate 实现。假设我有一个对象列表,必须将其保留在名为“事件”的表中。所有这些对象都具有相同的邮政编码。

public class Event {
    String id;
    String zipCode;
    String locationCode;
    String eventName;
    String eventDesc;
}

此处,id 是主键,zipCodelocationCode 一起构成唯一键 (UK_zipCode_locationCode)。该表可能已经包含具有给定邮政编码的对象。因此,我所做的不是查找​​应该添加、删除或更新哪些对象,而是先删除表中具有给定邮政编码的所有对象,然后插入所有给定对象。

// getEventsToAdd method returns the list of events to be added for the zipCode 1234
// getEventsFromTheDB method returns all the events in the db with the zipCode 1234 

List<Event> eventsToAdd = getEventsToAdd("1234");
List<Event> oldEvents = getEventsFromTheDB("1234");

for (Event e : oldEvents) {
    entityManager.remove(e);
}

for (Event e : eventsToAdd) {
    entityManager.persist(e);
}
entityManager.flush();
// ...

oldEvents 列表为空或者 oldEvents 中的所有对象也在 eventsToAdd 列表中时(我的意思是具有相同 id 和相同邮政编码的事件对象)。

但是,如果 oldEvents 中有一些事件对象具有不同的 id,即与 eventsToAdd 列表中任何对象的 id 不匹配,则会抛出异常异常(exception)

Duplicate Entry found for key UK_zipCode_locationCode

错误就好像旧事件没有从表中删除,现在插入具有相同 zipCode 和 locationCode 值的事件会导致 org.hibernate.exception.ConstraintViolationException

但是,如果我在删除旧事件后调用 entityManager.flush() ,它就会起作用 -

// This works!

for (Event e : oldEvents) {
    entityManager.remove(customizedProviderAttribute);
}
// flush after removing all the old events
entityManager.flush();
for (Event e : eventsToAdd) {
    entityManager.persist(e);
}

那么,为什么最后刷新不起作用,但删除旧实体后刷新却起作用?

最佳答案

默认情况下,EntityManager 在提交事务时执行所有 SQL 命令。但是,它可以决定执行 SQL 命令的顺序,在您的情况下,插入是在删除之前完成的,这会导致 ConstraintViolationExceptionflush() 使所有 SQL 立即执行,因此您可以实现先删除后插入。世界并不完美,Hibernate 也不是完美的。

关于java - EntityManager.remove 和 EntityManager.persist 上的 JPA 重复条目错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72057841/

相关文章:

java - Apache 希罗 : Using isAuthenticated() || isRemembered() for an app without high security requirements

java - 我怎样才能使这个查询只使用 JPA(或 Hibernate)API 工作?

java - Spring Controller 中的 PathVariable

java - 如何在 Spring 中获取单例 Controller 的原型(prototype) bean?

java - 配置更改无需重新部署

java - 数据库中的持久化日期不等于检索日期

java - hibernate 查询: new DTO clause not working

java - 模板模式,但其中一个类未实现该方法

java - 使用 Glassfish 的 EJB 客户端

java - 单例模式与使用一次对象?