如何避免在多对多双向关系中使用jpa将重复项插入到数据库中

时间:2017-04-30 17:54:22

标签: java json spring hibernate spring-data-jpa

我在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);

1 个答案:

答案 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);应执行此操作。