我有两张桌子
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);
答案 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
添加其他方法以添加联系人。您可以在此处找到更多信息: