Java Hibernate级联:取消引用子表中的父PK而不删除子对象

Java Hibernate级联:取消引用子表中的父PK而不删除子对象,java,hibernate,Java,Hibernate,如果父对象以包含3个子对象的列表开始,移除子对象1并调用session.update(父对象),我需要什么样的hibernate映射才能从移除的子表中清除父PK而不完全删除移除的子对象 我还有一个约束,它可以防止在任何子项被指定给父项时删除任何父项,还有一个约束可以防止我意外地级联删除任何子项 我可以通过简单地调用session.update(parent)成功地级联更新子级,但是我在做相反的事情时遇到了麻烦 public class Parent implements Serializable

如果父对象以包含3个子对象的列表开始,移除子对象1并调用session.update(父对象),我需要什么样的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;
  }
}
公共类父级实现可序列化{
私有静态最终长serialVersionUID=1L;
私人长id;
私人名单儿童;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@OneToMany(mappedBy=“家长”)
@org.hibernate.annotations.Cascade(
值={org.hibernate.annotations.CascadeType.SAVE_UPDATE})
公共列表getChildren(){
返回儿童;
}
公共子项(列出子项){
这个。孩子=孩子;
用于(儿童:儿童){
child.setParent(this);
}
}
//-----------------我需要这样的东西吗---------------
//-----------------还是冬眠有更好的方法---------------
公共子项(列出子项){
for(Child:this.childs)
如果(!children.contains(child)){
setParent(null);
}
}
这个。孩子=孩子;
用于(儿童:儿童){
child.setParent(this);
}
}
//----------------------------------------------------------------
}
公共类子级实现可序列化{
私有静态最终长serialVersionUID=1L;
私人长id;
私人家长;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@许多酮
公共父getParent(){
返回父母;
}
公共void setParent(父级){
this.parent=parent;
}
}
此解决方案类似,但我不是删除父项,而是从列表中删除子项:


我认为您必须手动将已删除元素的父元素设置为null。hibernate中没有任何东西可以为您做到这一点。通过使用来自BetterBeans绑定项目的。然后可以删除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);
       }
   }
}
公共类父类实现可序列化、可观察的Listener{
私有静态最终长serialVersionUID=1L;
私人长id;
私人名单儿童;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@OneToMany(mappedBy=“家长”)
@org.hibernate.annotations.Cascade(
值={org.hibernate.annotations.CascadeType.SAVE_UPDATE})
公共列表getChildren(){
返回儿童;
}
void listElementPropertyChanged(ObservableList列表,int索引){//Do Nothing}
void listlementereplaced(observeList列表,int索引,java.lang.Object oldElement){
listElementAdded(list.get(index));
listElementRemoved(oldElement);
}
void listlementsadded(可观察列表、整数索引、整数长度){
for(int i=索引;i<索引+长度;i++){
((子)list.get(i)).setParent(this);
}
}
void listElementsRemoved(ObservableList列表、int索引、java.util.list oldElements){
对于(对象元素:oldElements){
((子)list.get(i)).setParent(null);
}
}
}

如果对子表中的FK parent字段没有not null约束,则可以将parent设置为null并保存子项

我将使用以下方法编写:

Boolean removeChild(Child c) {
    Boolean success = getChildren().remove(c);
    if(success) c.setParent(null);
    return success;
 }
我会小心重写setChildren方法,因为hibernate需要普通的getter和setter