Hibernate OneToMany配置。需要帮助

时间:2017-05-23 07:46:18

标签: hibernate one-to-many

我有两张桌子

self.collectionView.register(UINib.init(nibName: "ImageCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: reuseIdentifier )

学生班是

Table Student  Columns (Rollnumber, ....)
Table Phone    Columns (STUD_ID,ID, phonetype, number)

电话课程

@Entity
@Table
public class Student {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  int rollNumber;

  @OneToMany
  Set<Phone> contacts;
  :
  : // Getter setters
}

}

但这不起作用

@Entity
public class Phone {

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  int id;
  @Column
  String type;
  @Column
  String number;
:
: // Getter setters

但是这不会在“电话”表中创建记录。在Phone类中,我不需要Student对象。 需要什么额外配置。

部分解决方案

最后我能够做到。通过使用“Cascade”和“joincolumn”如下。

        Student s1 = session.get(Student.class, 24);

        Phone p1 = new Phone();
        p1.setNumber("1111111");
        p1.setType("Ghar");


        Phone p2 = new Phone();
        p2.setNumber("222222");
        p2.setType("Office");


        Set<Phone> phoneSet = new HashSet<>();
        phoneSet.add(p1);
        phoneSet.add(p2);

        s1.setContacts(phoneSet);

        session.save(s1);

查询按以下方式触发(如预期的那样)

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="STUD_ID")
public Set<Phone> getContacts() {
    return contacts;
}

但如上所示,它会触发查询“更新电话设置STUD_ID = null其中STUD_ID =?”。我应该怎么做才会触发删除查询? 使用

Hibernate: select student0_.rollNumber as rollNumb1_3_0_, student0_.ADDR_ID as ADDR_ID4_3_0_, student0_.CLASS_TEACHER_ID as CLASS_TE5_3_0_, student0_.name as name2_3_0_, student0_.surname as surname3_3_0_, address1_.ID as ID1_0_1_, address1_.Country as Country2_0_1_, address1_.details as details3_0_1_, teacher2_.teacherId as teacherI1_4_2_, teacher2_.name as name2_4_2_, teacher2_.surname as surname3_4_2_ from Student student0_ left outer join ADDRESS address1_ on student0_.ADDR_ID=address1_.ID left outer join Teacher teacher2_ on student0_.CLASS_TEACHER_ID=teacher2_.teacherId where student0_.rollNumber=?
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: insert into Phone (number, stud_id, type, id) values (?, ?, ?, ?)
Hibernate: insert into Phone (number, stud_id, type, id) values (?, ?, ?, ?)
Hibernate: update Phone set STUD_ID=null where STUD_ID=?
Hibernate: update Phone set STUD_ID=? where id=?
Hibernate: update Phone set STUD_ID=? where id=?

抛出异常

@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)

解决方案

Caused by: org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.kaushik.winnersoft.data.Student.contacts

正如公认的解决方案所提到的那样改变了代码。

@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name="STUD_ID")
public Set<Phone> getContacts() {
    return contacts;
}

也解雇了删除查询。所有查询都是

s1.getContacts().clear();
Phone p1 = new Phone();
s1.getContacts().add(p1); 
Phone p2 = new Phone();
s1.getContacts().add(p2);

1 个答案:

答案 0 :(得分:1)

错误的原因

A collection with cascade="all-delete-orphan" was no longer referenced ...

是Hibernate使用代理跟踪orphanRemoval=true的集合。

所以你在持久化类中确实有一个代理(当你使用Student从数据库中获得session.get(Student.class, 24)时):

@Entity
@Table
public class Student {

  @OneToMany
  HibernateProxySet<Phone> contacts;

}

如果你这样做

s1.setContacts(phoneSet);

显然,您HibernateProxySet会覆盖HashSet。 Hibernate在这种情况下生成HibernateException,因为它希望使用HibernateProxySet跟踪contacts的所有更改。

如何解决

@Entity
@Table
public class Student {

  @OneToMany
  Set<Phone> contacts = new HashSet<>();

}

s1.getContacts().clear();
s1.getContacts().add(p1);
s1.getContacts().add(p2);

我已经contacts添加了new HashSet<>()字段初始化。当然,这不是强制性的,只是为了方便起见。您可以考虑在每个持久化类中使用此类策略。

此外,您可以考虑向Student添加其他方法以添加联系人。您可以在此处找到更多信息:

Hibernate - A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance