我在hibernate中有多对多的双向关系与实体Book and Author,作者可以写很多书,一本书可以有很多作者。 尝试使用已存在于数据库中的作者保存新书时出现问题。 hibernate将在数据库中创建一个具有新id的同一作者的新记录,如何将新书引用到数据库中的现有作者而不是创建新书?
我的课程看起来像这样。
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "author_id")
private Long id;
@Column(name = "name")
private String name;
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "authors")
private Set<Book> books = new HashSet<>();
书类
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "book_id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "abstract")
private String bookAbstract;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name = "book_author",
joinColumns = {@JoinColumn(name = "book_id")},
inverseJoinColumns = {@JoinColumn(name = "author_id")}
)
private Set<Author> authors = new HashSet<>();
我将JSON对象发送到其余控制器,然后保存该书
{
"name" : "Name of the Book",
"bookAbstract" : "an abstract",
"authors" : [
{"name":"Author1"},
{"name":"Author2"},
{"name":"Author3"}]}
我将JSON转换为java对象,并使用来自JPArepository的save()保存它,假设Author1已经在数据库中,下面的代码将创建Author1的新记录,
Book book = objectMapper.readerFor(Book.class).readValue(input);
bookRepository.save(book);
答案 0 :(得分:0)
我在这种情况下防止重复的方式是:
1)尝试获取每个作者的记录。假设您可以将存储库注入映射器,然后:
Book book = assembleBook(input);
for(String authorName: input.getAuthors){
Author author = repository.getAuthorByName(authorName);
if(author == null){
author = new Author(authorName);
}
author.getBooks().add(book);
book.getAuthors.add(author);
}
2)您可能需要执行bookRepository.merge(book);
,除非此调用与组装对象的事务处于同一事务中,然后bookRepository.saveOrUpdate(book);
应执行此操作。