Java Hibernate ElementCollection/JoinTable IntegrityConstraintViolationException
我有3个这样的JPA实体以及相应的JPA存储库Java Hibernate ElementCollection/JoinTable IntegrityConstraintViolationException,java,hibernate,spring-boot,spring-data-jpa,persistence,Java,Hibernate,Spring Boot,Spring Data Jpa,Persistence,我有3个这样的JPA实体以及相应的JPA存储库 @Entity public class ChairEntity { ... @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) @JoinTable(name = "chair_image") private Set<ImageEntity> images = new HashSet<>(); ... } @Entity public
@Entity
public class ChairEntity {
...
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "chair_image")
private Set<ImageEntity> images = new HashSet<>();
...
}
@Entity
public class TableEntity {
...
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "table_image")
private Set<ImageEntity> images = new HashSet<>();
...
}
@Entity
public class ImageEntity{
...
private String description;
@Lob
private byte[] data;
...
}
…或一次更新同一实体的多个ImageEntity
chairEntity.getImages().stream().forEach(imageEntity -> {
imageEntity.setDescription("some other description");
}
chairRepository.save(chairEntity);
在这两种情况下,所有更改都成功级联并保存
但是,如果我正在更新现有ImageEntity并添加另一个实体,则会失败:
chairEntity.getImages().stream().forEach(imageEntity -> {
imageEntity.setDescription("some other description");
}
chairEntity.getImages().add(new ImageEntity(...));
chairRepository.save(chairEntity); // crashes
异常如下所示(使用h2db引发等效错误):
检查数据库日志时,Hibernate似乎正在尝试:
为什么会发生这种情况?我该如何解决?在同一事务中单独保存和刷新更改似乎也不起作用。如果其他人遇到此问题,解决方法是:颠倒操作顺序:
chairEntity.getImages().add(new ImageEntity(...));
chairRepository.saveAndFlush(chairEntity);
chairEntity.getImages().stream().forEach(imageEntity -> {
imageEntity.setDescription("some other description");
}
chairRepository.save(chairEntity); // crashes
hibernate执行SQL语句的顺序保持不变,但由于之间的刷新,错误插入联接表的情况不再发生。@CollectionTable不应在此上下文中使用。它适用于字符串、枚举和可嵌入的基本类型,但不适用于实体:是的,你说得对。不过,hibernate在这个上下文中对待它的方式与@JoinTable相同。
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "chair_image_pkey"
chairEntity.getImages().add(new ImageEntity(...));
chairRepository.saveAndFlush(chairEntity);
chairEntity.getImages().stream().forEach(imageEntity -> {
imageEntity.setDescription("some other description");
}
chairRepository.save(chairEntity); // crashes