我正在尝试使用Java和Hibernate实现使用CRUD操作引用自身(同一类)的树。我的班级是:
@Entity
@Table(name="Person")
public class Person implements Comparable<Person>{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@ManyToOne(cascade = {CascadeType.ALL})
private Person father;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
private List<Person> children = new ArrayList<Person>();
}
插入效果很好,每次插入时我都会将人的父亲与人分开,并将人加入父亲的孩子。删除的时候,如果我删除了这个人,就会抱怨父亲引用了人名,如果我删除了父亲,就会抱怨父亲的id被人引用。那么,删除或更新的正确程序是什么?有类似的问题,但我找不到这个双向引用问题的确切解释。
答案 0 :(得分:0)
所以,由于@ Al1的mapped by
注释,我找到了解决问题的方法。但是,之后我无法检索LazyInitializationException
引起的对象,但能够删除树中的Leafs。
我已将private List<Person> children= new ArrayList<Person>();
更改为private Collection<Person> children = new LinkedHashSet<Person>();
该课程现在看起来像:
public class Person implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@ManyToOne(cascade = {CascadeType.ALL})
private Person father;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, mappedBy= "father")
private Collection<Person> children = new LinkedHashSet<Person>();
}
为了删除树节点,我不得不按Hibernate.initialize(this.getChildren());
加载子节点,然后递归删除每个节点。我的删除功能:
public static String deletePerson(Person p){
Transaction trns = null;
Session session = HibernateUtil.buildSessionFactory().openSession();
try {
trns = session.beginTransaction();
Hibernate.initialize(p.getChildren());
if (p.hasChildren()){
Collection<Person> children = p.getChildren();
for (Person person : children) {
deletePerson(person);
}
String hql = "delete from Person where name = :name";
session.createQuery(hql).setString("name", p.getName()).executeUpdate();
session.getTransaction().commit();
return "success";
}
else {
String hql = "delete from Person where name = :name";
session.createQuery(hql).setString("name", p.getName()).executeUpdate();
session.getTransaction().commit();
return "success";
}
} catch (RuntimeException e) {
if (trns != null) {
trns.rollback();
}
e.printStackTrace();
} finally {
session.flush();
session.close();
}
return "failure";
}
希望这可以帮助那些使用Hibernate和树的人:)