#java #hibernate #spring-data-jpa #many-to-many
#Ява #зимовать #весна-данные-jpa #многие ко многим
Вопрос:
У меня есть tbl_books
, с которым есть m2m tbl_author
. Я хочу спасти книгу и ее авторов. Я могу сохранить книгу, если не включу список авторов, но как я могу сохранить авторов в книге? Нужно ли мне создавать таблицу tbl_book_authors для достижения этой цели?
{ "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 Setlt;Authorgt; authors = new HashSetlt;gt;(); ...
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") Setlt;Bookgt; 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)
Ответ №1:
Вы не создавали первичный ключ автоматически в Book
сущности, и вы ничего не вставляете в JSON OBJECT
for id
, поэтому он 0
автоматически вставляет значение, если вы не вставляете какой-либо идентификатор в id
столбец, потому что вы передаете nullable = false
.
Поместите @GeneratedValue(strategy = GenerationType.IDENTITY)
для автоинкрементного первичного ключа.
public class Book { @Id @Column(name = "id", nullable = false) @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; ... ... }