Hibernate、单向manytone和对“On Delete Cascade”功能的渴望
我有一个问题与这里的问题相同: 搜索了一段时间后,我找不到合适/干净的解决方案。我不能让父实体与子实体有@OneToMany,因为它们位于不同的模块。我想尝试EntityListener,它会在父级之前删除子级,但我不能,因为它们位于不同的模块 有人知道一个干净的解决办法吗?我正在考虑使用AspectJ来监听ParentDao中delete方法的调用,但这不是一个干净的解决方案,我必须为与父类具有这种关系的每个实体实现一个Hibernate、单向manytone和对“On Delete Cascade”功能的渴望,hibernate,many-to-one,hibernate-cascade,Hibernate,Many To One,Hibernate Cascade,我有一个问题与这里的问题相同: 搜索了一段时间后,我找不到合适/干净的解决方案。我不能让父实体与子实体有@OneToMany,因为它们位于不同的模块。我想尝试EntityListener,它会在父级之前删除子级,但我不能,因为它们位于不同的模块 有人知道一个干净的解决办法吗?我正在考虑使用AspectJ来监听ParentDao中delete方法的调用,但这不是一个干净的解决方案,我必须为与父类具有这种关系的每个实体实现一个 这种级联似乎是一种基本功能,我很失望地看到hibernate不支持它:/
这种级联似乎是一种基本功能,我很失望地看到hibernate不支持它://您链接到的问题的答案是正确的。Hibernate只能在删除父对象时删除子对象,前提是父对象知道其子对象 唯一的解决方案是让ParentDAO的delete方法搜索父级的所有子级,删除它们,然后删除父级本身 如果您担心ParentDAO不应该知道子级,那么可以将其解耦,并让ParentDAO拥有一个注册的ParentDeletionListeners列表,该列表将在删除父级之前调用。ParentDAO只知道这个ParentDeletionListener接口,并允许注册多个侦听器。启动应用程序时,为每种类型的子项注册一个侦听器,并让侦听器删除子项:
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);
}
}
基于JB Nizet answer,我将我的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);
}
}
现在我有了一个不同的类,它可以在不改变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] 您的链接指向一个关于您所读过的最有影响的书的问题。与冬眠无关。请在这个问题中解释你的问题。对不起,链接错误的地方。编辑链接。这与EntityListenerpreDelete方法不同。这是一个很好的解决方案,但对于这种常见的问题,我们需要在hibernate中执行类似的操作,这让我感到困扰。不管怎样,谢谢你的回答:你被迫这么做是因为你选择了避免父母和孩子之间的耦合。我找到了一个通用的方法来做到这一点。我会在你允许的时候把它寄出去。谢谢你的想法,JB:
@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
}
}