删除和更新时出现外键冲突

时间:2017-11-08 08:16:50

标签: java postgresql hibernate

我正在尝试使用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被人引用。那么,删除或更新的正确程序是什么?有类似的问题,但我找不到这个双向引用问题的确切解释。

1 个答案:

答案 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和树的人:)