2017-11-08 12 views
0

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が参照されていることを訴えて、私は父親のIDが人によって参照されることを訴える。だから、削除や更新の正しい手順は何ですか?同様の質問がありますが、私はこの双方向参照問題の正確な説明を見つけることができません。

+0

外部キーはあなたが – JustMe

+0

がどのように追加することができますやりたいDELETE/UPDATE CASCADE'の整合性制約に '持っている必要がありますそれ? – FalseScience

+1

@ JustMeが述べたように、あなたのエラーはおそらくデータベースレベルです。 [データベースの外部キー定義](https://www.postgresql.org/docs/9.6/static/ddl-constraints.html#DDL-CONSTRAINTS-FK)を見てください。さらに、 '' mappedBy = "..." 'annotation](https://stackoverflow.com/q/11938253/4906586)をあなたの' children'定義に使用したくないのですか? – Al1

答えて

0

したがって、@ Al1のmapped byアノテーションのおかげで、問題の解決策が見つかりました。それでも、LazyInitializationExceptionのためにオブジェクトを取得できませんでしたが、ツリー内のLeafを削除できました。 、私はHibernate.initialize(this.getChildren());によって子をロードするためにしなければならなかったツリーノードを削除するために

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

して、再帰的にすべてのを削除します。 は、私はクラスが今のように見えるprivate List<Person> children= new ArrayList<Person>();

private Collection<Person> children = new LinkedHashSet<Person>();に変更することで、その問題を修正しましたノード。削除のMy機能:

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と木で動作する誰かを助け:)

関連する問題