问题描述
在我的数据库中,我有两个表Book和Label ,它们之间有ManyToMany关系。 我已经使用CascadeALL使用ManyToMany的注释在Hibernate中成功映射了它们。
现在考虑这种情况。
当我添加带有标签的新书列表时。 标签列表包含现有标签和新标签。 当书籍保存在数据库中时,它将创建现有标签的重复条目。 [意味着每次将使用不同的主键创建新标签(甚至对于现有标签),而不是使用现有的引用并更新ManyToMany表] 。我希望Hibernate更新现有标签并创建新标签。 同样,ManyToMany表也可以自行更新。
我可以想到手动解决方案。
- 保存没有标签的书。
- 将带有书本参考的现有标签和新标签与“书本”标签分开。
-
通过更新现有的标签
session.update()
并保存使用新session.save()
- ManyToMany表将自动更新。
但是我相信这是一种解决方案,几乎不需要冗长的编码和不必要的处理,并且可以改进。
Hibernate是否提供一些内置功能来解决此问题以及如何改进我的解决方案。
这是我的书本实体
@Entity
@XmlRootElement
public class Book {
@Id
@GeneratedValue
private int bookID;
private String bookName;
private String bookDescription;
private String bookAuthor;
private String bookEdition;
private String bookDownloadURL;
private String bookImageURL;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(name = "book_label", joinColumns = { @JoinColumn(name = "books_bookID") }, inverseJoinColumns = {
@JoinColumn(name = "labels_labelID") })
private List<Label> labels = new ArrayList<Label>();
//getters and setters
标签实体
@Entity
@XmlRootElement
public class Label {
@Id
@GeneratedValue
private int labelID;
private String labelName;
private String labelDesc;
@ManyToMany(mappedBy="labels",fetch=FetchType.EAGER)
private List<Book> books = new ArrayList<Book>();
// getter and setters
在我的数据库中,我已经创建了三个表
- col名称与Book实体的数据成员完全相同的book表
- col名称与Label实体的数据成员完全相同的label表
- 具有两列books_bookID,labels_labelID的book_label表。 这些列分别引用其他两个表格中的bookID和labelID(意味着它们实际上是外键)
这是我的测试用例代码
BookDAO booksDao = new BookDAO();
LabelDAO labelDao = new LabelDAO();
//Label by these name exist already in database.
//Upon adding the new book it should use the previous label and do entries in manytomany table accordingly
// (shouldn't create new labels with same names and map against them) <- THis is happening now
Label label1= new Label();
label1.setLabelName("Fantasy");
Label label2= new Label();
label2.setLabelName("Literature");
Book book1= new Book();
book1.setBookName("Talaash");
book1.getLabels().add(label1);
book1.getLabels().add(label2);
booksDao.addBook(book1);
1楼
如果我理解正确,您的问题是两个表都是该关系的所有者,因此这将导致重复的条目。 关系的所有者只有一个。 在您的班级之一中尝试以下操作:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "books")
public List<Label> getLabels()
在标签中,您应该有图书清单。 同样,这是我是否理解正确,因为您没有提供这些课程,以便我们进行更好的分析