更新Hibernate ManyToMany关系中的现有记录 [英] Update existing records in Hibernate ManyToMany Relation

查看:179
本文介绍了更新Hibernate ManyToMany关系中的现有记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的数据库中,我有两张 Book 标签,它们之间有 ManyToMany 关系。我已经使用 ManyToMany 通过 CascadeALL 注释了它们在Hibernate中的成功映射。现在考虑这种情况。



当我添加一个带有标签列表的新书时。标签列表包含现有标签和新标签。当书籍保存在数据库中时,它会创建现有标签的重复条目。每次使用不同的主键都会创建一个新的标签(即使是现有的标签),而不是使用现有的和更新的ManyToMany Table引用。我希望Hibernate更新现有标签并创建新的。类似的ManyToMany表会自行更新。



我可以想办法手动完成它。




  • 保存没有标签的图书。

  • 从图书标签中分离带书籍参考的现有标签和新标签。

  • 使用 session.update()更新现有标签,并使用 session.save()

  • ManyToMany表会自动更新。



但我相信这是一个解决方案,涉及很少冗长的编码和不必要的处理,并且可以改进。

是否有Hibernate提供一些内置功能来解决这个问题,以及如何改进我的解决方案。



这里是我的图书实体

  @Entity 
@XmlRootElement
public class Book {
@Id
@GeneratedValue
private int bookID;
私人字符串bookName;
private String bookDescription;
私人字符串bookAuthor;
private String bookEdition;
私人字符串bookDownloadURL;
私人字符串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
公共类标签{

@Id
@GeneratedValue
private int labelID;
私人字符串labelName;
私人字符串labelDesc;
@ManyToMany(mappedBy =labels,fetch = FetchType.EAGER)
private List< Book> books = new ArrayList< Book>();
// getter和setters

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


  1. 与col名称完全相同的书籍表与book实体的数据成员完全相同
  2. 标签表与col名称完全相同标签实体的数据成员
  3. 具有两列book_bookID,labels_labelID的book_label表。这些列分别引用来自其他两个表格的bookID和labelID(意味着它们实际上是外键)。

这里是我的测试用例代码

  BookDAO booksDao = new BookDAO(); 
LabelDAO labelDao = new LabelDAO();

//这些名称的标签已经存在于数据库中。
//在添加新书时,它应该使用之前的标签并相应地在多个表中输入条目
//(不应该使用相同名称创建新标签并映射它们)< - 这是现在发生

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


解决方案

如果我理解正确,是关系的所有者,所以这会导致重复的条目。只有一个班级应该是这种关系的所有者。在其中一个类中,尝试如下所示:

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

并且在您的标签中,您应该有图书清单。
再次,这是如果我理解正确,因为你不提供的类,以便我们有更好的分析


In my database I have two tables Book and Label with ManyToMany relation between them. I have mapped them successfully in Hibernate using annotation of ManyToMany with CascadeALL.

Now consider this scenario.

When I add a new Book with labels list. The list of label contain existing and new labels both. When the book is saved in the database it creates duplicate entries of existing labels. [Means each time a new label will be created (even for existing labels)with different primary key,rather than using the reference of existing and updating ManyToMany Table] .I want Hibernate to update existing labels and create new ones. Similarly ManyToMany table to be updated itself.

I can think of solution of doing it manually.

  • Save the Book without labels.
  • Separating the existing and new labels with book reference, from Book labels.
  • Update the existing labels using session.update() and save the new using session.save()
  • The ManyToMany table will be automatically updated.

But I believe this is solution involve little lengthy coding and unnecessary processing, and can be improved.

Is there Hibernate provide some builtin feature to cater this problem and how my solution can be improved.

Here goes my Book Entity

@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

Label Entity

@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

In my database I have three tables created already

  1. book table with col name exactly same as datamembers of Book entity
  2. label table with col name exactly same as datamembers of Label entity
  3. book_label table with two column books_bookID, labels_labelID. These column are referencing bookID and labelID from other two tabels respectively (means they are foreign keys actually)

And here is my test case code

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

解决方案

If I understand correctly, your problem is that both tables are owners of the relationship, so this results in duplicate entries. Only one class should be owner of the relationship. In one of yout class try something like:

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

and in your label you should have books list. Again this is if i understand correctly because you do not provide the classes so that we have a better analysis

这篇关于更新Hibernate ManyToMany关系中的现有记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆