2011-12-05 20 views
0

私はここで提示された1つに等しいです問題があります。how to define an inverse cascade delete on a many-to-one mapping in hibernateHibernateは、一方向のManyToOneおよび「オンカスケードの削除」機能への要望

しばらく検索した後、私はまともな/きれいな解決策を見つけることができませんがこのため。彼らは異なるモジュールにあるので、親エンティティに@OneToManyを持つことはできません。私は、親が存在する前に子を削除するEntityListenerを試したかったのですが、別のモジュールにあるため再配置できません。

誰もがこれに対してクリーンな解決法を知っていますか?私はAspectJを使ってParentDaoからdeleteメソッドの呼び出しを聞こうと考えていますが、これはクリーンな解決策ではなく、Parentクラスに対するこの種の関係を持つ各エンティティに対して1つ実装する必要があります。

カスケードのこの種のは、基本的な機能のようだと私はHibernateがそれをサポートしていないことを見ることに一種がっかりしています:/

+1

あなたのリンクポイントに関する質問へあなたが読んだ最も激しい本。 Hibernateとは関係ありません。この質問であなたの問題を説明してください。 –

+0

申し訳ありませんが、リンク先が間違っています。リンクの編集。 –

答えて

1

私はDeleteOperationListener(マイベースDAOの実装が基づいて持っている私のDAOを変更"DAOを繰り返さないでください" [1]。)このようにして、私は自分自身が同じ状況に再び遭遇した場合に備えて、包括的な解決策を持っています。構造は次のようになります。

私の抽象的な休止状態の実装では、削除についてオブザーバーに通知できます。

@Override 
public void delete(T entityToDelete) { 
    notifyPreDelete(entityToDelete); 
    this.getHibernateTemplate().delete(entityToDelete); 
    notifyPosDelete(entityToDelete); 
} 

そして今、私はのDAOを変更することなく、子どもの削除を扱う別のクラスを持っている:

@Service 
public class ParentModificationListener 
    implements GenericDao.DeleteOperationListener<Parent> { 

    private ChildDao childDao; 

    @Autowired 
    public ParentModificationListener(ChildDao childDao, ParentDao parentDao) { 
     this.childDao = childDao; 
     parentDao.addDeleteListener(this); 
    } 

    @Override 
    public void preDelete(Parent parent) { 
     this.childDao.deleteChildrenFromParent(parent); 
    } 

    @Override 
    public void posDelete(Parent parent) { 
     // DO NOTHING 
    } 
} 

[1] http://www.ibm.com/developerworks/java/library/j-genericdao.html

2

あなたがにリンクされ、質問の答えが正しいです。 Hibernateは、親がその子を知っている場合にのみ、親を削除するときに子を削除することができます。

唯一の解決策は、親のすべての子を検索して削除し、親自体を削除するParentDAOの削除メソッドを持つことです。

ParentDAOが子供について知ってはならないことが懸念される場合は、それを分離して、ParentDAOに登録されたParentDeletionListenersのリストを持たせることができます。 ParentDAOはこのParentDeletionListenerインターフェイスのみを認識し、複数のリスナーの登録を許可します。アプリケーションを起動すると、子供のあらゆる種類のリスナーを登録し、リスナーが子供を削除します:JB Nizetの回答に基づいて

public interface ParentDeletionListener { 
    void parentWillBeDeleted(Parent parent); 
} 

public class SomeChildParentDeletionListener implements ParentDeletionListener { 
    // ... 
    public void parentWillBeDeleted(Parent parent) { 
     // search for every SomeChild linked to the given parent 
     // and delete them 
    } 
} 

public class ParentDAO { 
    private List<ParentDeletionListener> listeners = new CopyOnWriteArrayList(); 

    public void addParentDeletionListener(ParentDeletionListener listener) { 
     this.listeners.add(listener); 
    } 

    public void deleteParent(Parent p) { 
     for (ParentDeletionListener listener : listeners) { 
      listener.parentWillBeDeleted(parent); 
     } 
     session.delete(parent); 
    } 
} 
+0

これはEntityListener#preDeleteメソッドとは異なるアプローチです。それは良い解決策ですが、このような一般的な問題のために、冬眠中にこのようなことをする必要があることは私には気になります。とにかく答えをありがとう:) –

+0

あなたは子供と親を結合することを避けることを選んだので、あなたはそれをする必要があります。 –

+0

これを行う一般的な方法が見つかりました。私はそれを投稿するときにstackoverflowさせてください。アイデアJBに感謝:) –

関連する問題