如果父对象以3个子对象的列表开始,删除子1并调用session.update(parent),我需要什么样的hibernate映射才能从已删除的子表中清除父PK完全删除被删除的孩子?
我还有一个约束,它可以防止任何父项被分配给任何子项,而另一个约束会阻止我意外地级联删除任何子项。
我可以通过简单地调用session.update(parent)来成功级联更新子项,但是我在反向时遇到了麻烦。
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private List<Child> children;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(mappedBy = "parent")
@org.hibernate.annotations.Cascade(
value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children){
this.children = children;
for(Child child : children) {
child.setParent(this);
}
}
//----------------- Would I need something like this? ---------------
//----------------- Or does hibernate have a better way? ---------------
public void setChildren(List<Child> children){
for(Child child : this.children)
if (!children.contains(child)) {
child.setParent(null);
}
}
this.children = children;
for(Child child : children) {
child.setParent(this);
}
}
//----------------------------------------------------------------
}
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Parent parent;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
此解决方案类似,但我没有删除Parent,而是我从列表中删除了一个Child:
答案 0 :(得分:0)
我认为您必须手动将已删除元素的父级设置为null。休眠中没有任何东西能为你做到这一点。使用Better Beans Binding Project中的Observable Collection可以做得更好。然后,您可以删除您的setter,并立即反映更改。
public class Parent implements Serializable, ObservableListListener {
private static final long serialVersionUID = 1L;
private Long id;
private List<Child> children;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(mappedBy = "parent")
@org.hibernate.annotations.Cascade(
value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
public List<Child> getChildren() {
return children;
}
void listElementPropertyChanged(ObservableList list, int index) { // Do Nothing }
void listElementReplaced(ObservableList list, int index, java.lang.Object oldElement) {
listElementAdded(list.get(index));
listElementRemoved(oldElement);
}
void listElementsAdded(ObservableList list, int index, int length) {
for(int i = index; i < index + length; i++) {
((Child)list.get(i)).setParent(this);
}
}
void listElementsRemoved(ObservableList list, int index, java.util.List oldElements) {
for(object element : oldElements) {
((Child)list.get(i)).setParent(null);
}
}
}
答案 1 :(得分:0)
如果子表中的FK父字段没有非空约束,则可以将parent设置为null并保存子项。
我会写下面的方法:
Boolean removeChild(Child c) {
Boolean success = getChildren().remove(c);
if(success) c.setParent(null);
return success;
}
我要小心覆盖setChildren方法,因为hibernate需要普通的getter和setter。