[英]Avoid add same data with many-to-many relationship jpa
我有一種情況,一本書可能有一個類別,並且屬於多個作者。 一個類別可能有很多書籍。 作者可能屬於很多書籍。
所以,
Book
到Book
BookCategory
是many-to-one
Book
以Author
和Author
對Book
是many-to-many
(在book_author
表) BookCategory
to Book
是one-to-many
我可以和作者以及類別一起保存(使用以下代碼)新書。 但是,問題是:
Author
表中是否已經存在該Author
,則該作者將再次插入到Author
表中 Author
表中是否已存在同一作者,然后從列表中省略該作者,那么book_author
表如何知道該書是否與已存在的作者有關系? 這是我聲明實體和服務的方式:
BookDto
public class BookDto {
private String title;
private String year;
private Set<AuthorDto> author;
private String category;
}
作者Dto
public class AuthorDto {
private String name;
private String address;
}
書
@Entity(name = "book")
@Table(name = "book", uniqueConstraints = {@UniqueConstraint(columnNames = {"id"})})
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title", nullable = false)
private String title;
@Column(name = "year", nullable = false)
private String year;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name = "book_author",
joinColumns = @JoinColumn(name = "book_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "author_id", referencedColumnName = "id"))
@JsonManagedReference
private Set<Author> author;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private BookCategory category;
}
作者
@Entity(name = "author")
@Table(name = "author", uniqueConstraints = {@UniqueConstraint(columnNames = {"id"})})
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "address", nullable = false)
private String address;
@ManyToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JsonBackReference
private Set<Book> book;
}
圖書類別
@Entity(name = "book_category")
@Table(name = "book_category")
public class BookCategory {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "category", nullable = false)
private String category;
}
BookServiceImpl
public class BookServiceImpl implements BookService {
public BookDto save(BookDto bookDto) throws Exception {
try {
Book book = new Book();
BeanUtils.copyProperties(bookDto, book, "author", "category");
BookCategory bookCategory = bookCategoryDao.findByCategory(bookDto.getCategory());
Set<Author> dataAuthor = new HashSet<Author>();
Set<AuthorDto> dataAuthorDto = new HashSet<AuthorDto>();
bookDto.getAuthor().iterator().forEachRemaining(dataAuthorDto::add);
for (AuthorDto authorDto : dataAuthorDto) {
Author author = new Author();
/**
* Problem is:
* 1. If I did not check whether the author already exist in
* Author table, the same author will inserted again into Author table
* 2. If I check whether same author already exist in Author table, then omit
* the author from the list, how book_author table would know if
* the book have relationship with already existed author?
* */
BeanUtils.copyProperties(authorDto, author);
dataAuthor.add(author);
}
book.setAuthor(dataAuthor);
book.setCategory(bookCategory);
bookDao.save(book);
} catch (Exception e) {
throw new Exception(e);
}
return null;
}
}
任何幫助都將非常有幫助。 謝謝!
如果我沒有檢查作者表中是否已經存在該作者,則該作者將再次插入到作者表中
正確。 得出的結論是,如果您不希望重復,那么無論您對“同一”作者的業務定義是什么,都應該檢查該作者是否已經存在。
如果我檢查“作者”表中是否已存在同一作者,然后從列表中省略該作者,那么book_author表如何知道該書是否與已存在的作者有關系?
好吧,那就不要忽略它。 查找它。 假設您對同一作者的定義是“具有相同名稱的作者”,只需將以下方法添加到DataAuthorRepository
(或您所謂的任何名稱)中:
Optional<Author> findByNameIgnoreCase(String name)
然后,在BookServiceImpl
,只需執行以下操作:
for (AuthorDto authorDto : dataAuthorDto) {
Author author = dataAuthor.findByNameIgnoreCase(authorDto.getName())
.orElseGet(() -> {
Author newAuthor = new Author();
BeanUtils.copyProperties(authorDto, newAuthor);
return newAuthor;
});
dataAuthor.add(author);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.