我与实体书籍和作者有许多与实体的双向关系,作者可以写很多书,一本书可以有很多作者。试图与已经在数据库中的作者保存新书时出现的问题。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对象发送到REST控制器,然后保存本书
{
"name" : "Name of the Book",
"bookAbstract" : "an abstract",
"authors" : [
{"name":"Author1"},
{"name":"Author2"},
{"name":"Author3"}]}
i将JSON转换为Java对象,并且使用JPAREPOSITORY的Save((save((将其保存,假设ruter1已经在数据库中,则下面的代码将创建一个新记录,
Book book = objectMapper.readerFor(Book.class).readValue(input);
bookRepository.save(book);
好吧,在您的情况下,我阻止重复的方式是:
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);
应该这样做。