为什么我从 Hibernate 多对多关系(外键约束)中得到 java.sql.SQLIntegrityConstraintViolationException

Why do I get a java.sql.SQLIntegrityConstraintViolationException from a Hibernate many to many relation (foreign key constraint)

我有 tbl_books,其中有 m2m 和 tbl_author。我想保存一本书及其作者。如果我不包含作者列表,我可以保存这本书,但我应该如何将作者保存到书中?我是否需要创建 tbl_book_authors table 才能实现此目的?

{
    "title": "a new book",
    "publisher": {
        "id": 7
    },
    "authors": [
        {
            "id": 3
        }
    ]
}

Book.java

...
@NoArgsConstructor
@Entity(name="Book")
@Table(name="tblBook")
public class Book {

    @Id
    @Column(name = "id", unique = true, nullable = false)
    private int id;
    private String title;
    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "pub_id", nullable = false)
    private Publisher publisher;
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "tblBookAuthors",
            joinColumns = { @JoinColumn(name = "bookId") },
            inverseJoinColumns = { @JoinColumn(name = "authorId") })
    private Set<Author> authors = new HashSet<>();
    ...

author.java

...
@NoArgsConstructor
@Entity(name="Author")
@Table(name="tblAuthor")
public class Author {

    @Id
    @Column(name = "id")
    private int id;
    @Column(name = "name")
    private String name;
    @JsonBackReference
    @ManyToMany(mappedBy = "authors")
    Set<Book> books;

    ...

日志

Book{id=0, title='a new book', publisher=Publisher{id=7, name='null', address='null', phone='null', books=null}, authors=[Author{id=3, name='null', books=null}]}
Hibernate: select publisher_.id, publisher_.address as address2_4_, publisher_.name as name3_4_, publisher_.phone as phone4_4_ from tbl_publisher publisher_ where publisher_.id=?
Hibernate: insert into tbl_book (pub_id, title, id) values (?, ?, ?)
Hibernate: insert into tbl_book_authors (book_id, author_id) values (?, ?)
2021-11-27 18:49:06.643  WARN 8704 --- [nio-8080-exec-7] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1452, SQLState: 23000
2021-11-27 18:49:06.643 ERROR 8704 --- [nio-8080-exec-7] o.h.engine.jdbc.spi.SqlExceptionHelper   : Cannot add or update a child row: a foreign key constraint fails (`library`.`tbl_book_authors`, CONSTRAINT `fk_tbl_book_authors_tbl_book1` FOREIGN KEY (`book_id`) REFERENCES `tbl_book` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
2021-11-27 18:49:06.644  INFO 8704 --- [nio-8080-exec-7] o.h.e.j.b.internal.AbstractBatchImpl     : HHH000010: On release of batch it still contained JDBC statements
2021-11-27 18:49:06.663 ERROR 8704 --- [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause

java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`library`.`tbl_book_authors`, CONSTRAINT `fk_tbl_book_authors_tbl_book1` FOREIGN KEY (`book_id`) REFERENCES `tbl_book` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

您没有在 Book 实体中自动增加主键,并且您在 JSON OBJECT 中没有为 id 插入任何内容,因此如果您不插入,它会自动插入 0id 列中的任何 id,因为您传递了 nullable = false.

为自增主键输入@GeneratedValue(strategy = GenerationType.IDENTITY)

public class Book {

    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    ...
    ...
}