冬眠、単方向の多数、および「削除カスケード」機能への欲求
-
28-10-2019 - |
質問
ここで提示されているものと等しい問題があります。 Hibernateでの多面マッピングで逆カスケード削除を定義する方法
しばらく検索した後、これについてはまともな/きれいな解決策が見つかりません。親のエンティティに子供に@Onetomanyを持たせることはできません。なぜなら、それらは異なるモジュールにいるからです。親の前に子供を削除するentitityListenerを試してみたかったのですが、繰り返しますが、彼らは異なるモジュールにいるからです。
誰かがこれに対するきれいな解決策を知っていますか?私はAspectJを使用してParentDaoから削除メソッドのCall of the Deleteメソッドを聞くことを考えていますが、これはクリーンな解決策ではなく、この種の親クラスとこの種の関係を持つエンティティごとに実装する必要があります。
この種のカスケードは基本的な機能のようであり、私は冬眠がそれをサポートしていないことを見て、私は親切に失望しています:/
解決 2
jb nizetの回答に基づいて、DAOを変更してdeleteOperationListener(私の基本DAOの実装は「DAOを繰り返さないでください」[1]に基づいています。)このように、同じように自分自身を見つけた場合の一般的なソリューションがあります。再び状況。構造は次のようになります:
public interface GenericDao<T, PK extends Serializable> {
// CRUD methods
// delete operation listeners.
void addDeleteListener(DeleteOperationListener<T, PK> deleteOperationListener);
public interface DeleteOperationListener<T> {
void preDelete(T entity);
void posDelete(T entity);
}
}
そして、私の抽象的な冬眠の実装は、削除についてオブザーバーに通知することができます。
@Override
public void delete(T entityToDelete) {
notifyPreDelete(entityToDelete);
this.getHibernateTemplate().delete(entityToDelete);
notifyPosDelete(entityToDelete);
}
そして今、私はDAOSを変更する必要なく、子供の削除を処理する別のクラスを持っています。
@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
他のヒント
あなたがリンクした質問の答えは正しいです。 Hibernateは、親が子供について知っている場合に親を削除するときにのみ子供を削除できます。
唯一の解決策は、親のすべての子供を検索し、それらを削除してから親自体を削除するために、ParentDaoの削除方法を持つことです。
ParentDaoが子供について知らないことを懸念している場合、それを分離することができ、ParentDaoに登録されたParentDeletionListenersのリストを持たせることができます。 ParentDaoは、このParentDelitionListenerインターフェイスについてのみ知っており、複数のリスナーを登録できます。アプリケーションを開始するときは、あらゆる種類の子供のリスナーを登録し、リスナーに子供を削除してもらいます。
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);
}
}