更新Hibernate ManyToMany Relation

时间:2015-07-31 05:30:44

标签: java hibernate jpa orm many-to-many

在我的数据库中,我有两个表 Book Label ManyToMany 关系。我使用 ManyToMany 的注释和 CascadeALL 在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

在我的数据库中,我已经创建了三个表

  1. 书目表,其名称与书籍实体的数据名称完全相同
  2. 标签表,其col名称与Label实体的数据名称完全相同
  3. book_label表有两列books_bookID,labels_labelID。这些列分别引用其他两个表格中的bookID和labelID(实际上意味着它们是外键)
  4. 这是我的测试用例代码

        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 个答案:

答案 0 :(得分:3)

如果我理解正确,您的问题是两个表都是关系的所有者,因此会导致重复的条目。只有一个班级应该是这段关系的所有者。在其中一个类中尝试类似:

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "books")
public List<Label> getLabels()

在你的标签上你应该有书籍清单。 再次,如果我理解正确,因为你没有提供类,以便我们有更好的分析