【发布时间】:2020-01-06 20:16:56
【问题描述】:
我有两个表book和page 我正在尝试在它们之间建立一个双向的一对多关系。
页面 对无法正常工作的多个列有唯一约束。当我插入具有唯一 page_item 的 book_item 时,它按预期工作,但是当我尝试删除也应该删除页面的书时,我得到 唯一约束违反异常,我真的不明白。 我正在使用 jpa 存储库来执行插入/删除。
当我删除 @UniqueConstraint 时,删除有效,但约束也无效,所以我真的不明白我做错了什么。
@Entity
@Table(name = "book")
@NoArgsConstructor
@RequiredArgsConstructor
public class Book implements Serializable {
@Id
@GeneratedValue(generator = "book_uuid")
@GenericGenerator(name = "book_uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)")
@Type(type="uuid-char")
@Getter
private UUID id;
@OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
@Getter
@Setter
private List<Page> pages;
}
@Entity
@Table(name = "page", uniqueConstraints = @UniqueConstraint(columnNames = {"book_id", "chapter", "volume", "name"}))
@NoArgsConstructor
@RequiredArgsConstructor
public class Page implements Serializable {
@Id
@GeneratedValue(generator = "page_uuid")
@GenericGenerator(name = "page_uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)")
@Type(type="uuid-char")
@Getter
private UUID id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "book_id", nullable = false)
@Getter
@Setter
@NonNull
private Book book;
@Column(name = "chapter", nullable = false)
@Getter
@Setter
private int chapter = 0;
@Column(name = "volume", nullable = false)
@Getter
@Setter
private int volume = 0;
@Column(name = "name", nullable = false)
@Getter
@Setter
@NonNull
private String name;
}
// Code used for insertion/update /deletion
@Repository
public interface BookRepository extends JpaRepository<Book, UUID> {
}
public void test() {
Book book = bookRepository.findById("9c7b2ab2-1c78-4e9f-adc5-99c7da42a7c6");
List<Page> pages = IntStream.range(0, 5)
.mapToObj(i -> new Page(book, "Page" + i, ".png"))
.collect(Collectors.toList());
book.setPages(pages);
bookRepository.save(book);
bookRepository.delete(book);
我得到的错误信息:
org.springframework.dao.DataIntegrityViolationException:无法执行语句; SQL [不适用];约束 ["UKOBQWYIY89PIIE6GP2NB4PVQ8W_INDEX_2 ON PUBLIC.PAGE(BOOK_ID, CHAPTER, VOLUME, NAME) VALUES ('acb0bb92-be2f-4dd3-9653-98f8d890e6b4', 0, 0, 'Page0', 1)"; SQL语句:
插入页面(book_id、章节、扩展名、名称、卷、id)值(?,??,?,?,?,?)[23505-197]];嵌套异常是 org.hibernate.exception.ConstraintViolationException: could not execute statement
【问题讨论】:
-
我不会依赖级联,因为它会执行许多 SQL 查询,并删除您可能不希望删除的可能与其他实体相关的实体。而是通过执行您自己的 DELETE 语句或手动删除来管理它。有关更多信息,请参阅thoughts-on-java.org/avoid-cascadetype-delete-many-assocations。请发布您添加/删除书籍的代码。
-
我添加了一个简单的代码 sn-p 进行插入和删除,当我执行这个时,我得到了帖子中提到的错误。
-
首先,将@Transactional 放入您的存储库中,然后将方法deleteById 映射为javaNoob 的建议,然后让级联孤儿删除就可以了
标签: java hibernate spring-boot