我正在使用JPA的Hibernate实现.假设我有一个对象列表,我必须将其保存在一个名为Event的表中.所有这些对象都有相同的邮政编码.

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不匹配,则它会抛出异常

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命令的顺序,在您的例子中,插入是在删除之前完成的,这导致了ConstraintViolationException次.flush()会立即执行所有SQL,因此可以在插入之前实现删除.世界并不完美,冬眠也不完美.

Java相关问答推荐

Java -使用空比较或instanceof?

伪类focus-in不适用于PFA中的选项卡

转换为Biggram

在Java中测试DAO方法:假实现与内存数据库

CAMEL 4中的SAXParseException

Mapstruct不能正确/完全映射属性

暂停计时器

对于亚洲/香港,使用ResolverStyle.STRICT的LocalDate.parse返回意外结果

Java连接池无法正常工作

在Frege中,我如何将一个字符串安全地转换为一个可能的Int?

Spring Boot&;Docker:无法执行目标org.springframework.boot:spring-boot-maven-plugin:3.2.0:build-image

我可以在@Cacheable中使用枚举吗

对从Spring Boot 3.1.5升级到3.2.0的方法的查询验证失败

插入中的JOOQ序列,设置为VS值

TinyDB问题,无法解析符号';上下文&

无限递归Java问题

如何使用带有可选参数的类生成器?

由于版本不匹配,从Java 8迁移到Java 17和Spring 6 JUnit4失败

java21预览未命名的符号用于try-with-resources

OpenAPI Maven插件生成错误的Java接口名称