我正在开发一个具有许多外键关系的应用程序,这些关系具有与之相关的一些相当复杂的业务逻辑。我们经常需要将一个子项添加到父项(有时是一个全新的,有时从另一个父项移动),然后在同一个hibernate会话中查找父项的所有子项。例如,我们有基本上执行以下操作的逻辑:
private void move(Child c1) {
if ( shouldSplit(c1) ) {
Child c2 = copy(c1);
c2.setParent(p);
p.getChildren().add(c2);
childDAO.create(c2);
if ( shouldMove(c2) ) {
move(c2);
}
}
c1.setStatus(nextStatus(c1));
if ( isTerminal(c1.getStatus()) ) {
boolean allTerminal = true;
for(Child c3 : c1.getParent().getChildren()) {
if ( !isTerminal(c3) ) {
allTerminal = false;
break;
}
}
if ( allTerminal ) {
finalize(p);
}
}
}
我们遇到的问题是很容易忘记“p.getChildren()。add(c2)”步骤。如果忘记了这一点,那么“isTerminal”检查将忽略在同一会话中创建的所有新子节点,并错误地假设一切都处于终端状态。我们想在每次说“child.setParent(p)”时都这样做,它会将子节点添加到它的新父节点的反向外键集合中(如果它有前一个父节点,则从它的前一个父集合中删除它)。 / p>
我们现在的Hibernate对象是由hbm2java生成的,导致父进程如下:
@OneToMany(fetch=FetchType.LAZY, mappedBy="parent")
public Set<Child> getChildren() {
return this.children;
}
public void setChildren(Set<Child> children) {
this.children = children;
}
对于孩子:
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="PARENTID", nullable=false)
public Parent getParent() {
return this.parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
不幸的是,由于我们当前的设置方式,我们没有选择直接修改生成的java类,并为子项添加“parent.getChildren()。add(this)”行(我们可能赢了)由于其他优先事项,我们可以在至少一年的时间内完成任务。
在设置/取消设置孩子的父母时,Hibernate或hbm2java中是否有任何选项可以消除更新父母的子集合的需要?