I am not able to add new Book with existing Genre in SpringBoot from json in Postman. It says 'constraint [\"PRIMARY KEY ON PUBLIC.GENRE(GENRE_ID)'.
Here is my model:
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Data
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="book_id")
private Integer Id;
private String title;
private String imgurl;
private String description;
private String bookpath;
@ManyToOne
private Author author;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "book_genre",
joinColumns = @JoinColumn(name="book_id"),
inverseJoinColumns = @JoinColumn(name="genre_id"))
private List<Genre> genres;
public void addGenre(Genre genre){
this.genres.add(genre);
genre.getBooks().add(this);
}
}
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
@Table(name = "genre")
public class Genre {
@Id
@Column(name="genre_id")
private Integer id;
private String name;
@JsonIgnore
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="book_genre",
joinColumns=@JoinColumn(name="genre_id"),
inverseJoinColumns=@JoinColumn(name="book_id"))
private List<Book> books;
public List<Book> getBooks(){
return this.books;
}
}
I am working with jpa Repository. Here is my book controller post method:
@PostMapping("/books")
Book createBook(@RequestBody Book book){
return this.bookRepository.save(book);
}
In postman I have this:
{
"title": "Evgenij Onegin",
"imgurl": "https://biblioteka.msu.edu.mk/images/covers/2018/September/5bab75a75007c/821.806.jpeg",
"description": "desctiption",
"bookpath": "Books\\book1.pdf",
"author": {
"name": "Alexandar",
"surname": "Puskin",
"birthdate": "1799-06-05",
"description": "Russian author",
"location": "Russia",
"category": {
"name": "Romantism",
"id": 1
},
"id": 1
},
"genres": [
{
"id": 1,
"name": "Trailer"
},
{
"id": 2,
"name": "Comic"
}
]
}
And the error I am getting:
constraint [\"PRIMARY KEY ON PUBLIC.GENRE(GENRE_ID)'.
So it seems like the problem is in ManyToMany relationship. Without adding Genre to Book it works perfect, but I want to add it.
You are doing the ManyToMany
association incorrect. You are defining the JoinTable
on the both end
public class Book {
...
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE } )
@JoinTable(name = "book_genre",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "genre_id")
)
private List<Genre> genres;
...
}
And on the other side in Genre
you just do this
public class Genre {
...
@ManyToMany(mappedBy = "genres")
private List<Book> books;
...
}
This is a very good article about The best way to use the @ManyToMany annotation with JPA and Hibernate This will help you understading the association mappings.
You should have used CascadeType.PERSIST
in both of your @ManyToMany
mappings for Books and Genre. Also, books
in Genre entity should be mapped by genres
collection.
// Book entity:
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinTable(name = "book_genre",
joinColumns = @JoinColumn(name="book_id"),
inverseJoinColumns = @JoinColumn(name="genre_id"))
private List<Genre> genres;
// Genre entity:
@ManyToMany(mappedBy = "genres", fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
private List<Book> books;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.