Spring Data JPA与Hibernate多对多保存冲突问题咨询
Spring Data JPA多对多关联保存重复唯一键异常问题
Book.java 实体代码
public class Book { @Id private int id; private String title; @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @JoinTable(name = "author_book", joinColumns = @JoinColumn(name = "book_id"), inverseJoinColumns = @JoinColumn(name = "author_id")) private Set<Author> authors = new HashSet<>(); // 构造方法、setter、getter、equals和hashCode已省略 // equals和hashCode实现中未包含authors集合 public void addAuthor(Author author) { authors.add(author); author.getBooks().add(this); }
Author.java 实体代码
public class Author { @Id private int id; private String name; @Column(unique = true) private String phoneNumber; @ManyToMany(mappedBy = "authors") private Set<Book> books = new HashSet<>(); // 构造方法、setter、getter、equals和hashCode已省略 // equals和hashCode实现中未包含books集合 public void addBook(Book book) { books.add(book); book.getAuthors().add(this); }
问题场景
当尝试保存关联同一已存在作者的书籍时,抛出唯一键重复异常。
Spring Data JPA测试代码
@Bean ApplicationRunner applicationRunner(BookRepository bookRepository) { return args -> { Author a1 = new Author("author1", "phone1"); Author a2 = new Author("author2", "phone2"); Author a3 = new Author("author3", "phone3"); Book b1 = new Book(); b1.setId("id1"); b1.setName("book1"); b1.setAuthors(Set.of(a1, a2)); Book b2 = new Book(); b2.setId("id2"); b2.setName("book2"); b2.setAuthors(Set.of(a1, a3)); bookRepository.save(b1); bookRepository.save(b2); }; }
抛出的异常信息
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "authors_phone_number_key" Detail: Key (phone_number)=(phone1) already exists.
纯Hibernate执行对比
使用纯Hibernate执行相同逻辑,代码如下:
try (EntityManager em = emf.createEntityManager()) { em.getTransaction().begin(); Author a1 = new Author("author1", "phone1"); Author a2 = new Author("author2", "phone2"); Author a3 = new Author("author3", "phone3"); Book b1 = new Book(); b1.setId("id1"); b1.setName("book1"); b1.setAuthors(Set.of(a1, a2)); Book b2 = new Book(); b2.setId("id2"); b2.setName("book2"); b2.setAuthors(Set.of(a1, a3)); em.persist(b1); em.persist(b2); em.getTransaction().commit(); }
执行结果符合预期:
- authors表新增3条记录
- books表新增2条记录
- author_book关联表新增4条记录
疑问
使用Spring Data JPA时是否遗漏了某些配置?它是否覆盖了Hibernate的默认行为?
内容的提问来源于stack exchange,提问作者Mohammad Ballour
相关产品推荐
相关产品推荐

