【问题标题】:Hibernate Cascade: De-reference parent PK in child table without removing child objectHibernate Cascade:在子表中取消引用父PK而不删除子对象
【发布时间】:2011-07-15 18:01:37
【问题描述】:

如果父对象从 3 个子对象的列表开始,删除子 1 并调用 session.update(parent),我需要什么样的休眠映射才能从删除的子表中清除父 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;
  }
}

此解决方案类似,但我没有删除父级,而是从列表中删除一个子级:

hibernate cascade - update child to null

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    如果子表中的FK父字段没有非空约束,可以直接设置parent为null,保存子表即可。

    我会写以下方法:

    Boolean removeChild(Child c) {
        Boolean success = getChildren().remove(c);
        if(success) c.setParent(null);
        return success;
     }
    

    我会小心覆盖 setChildren 方法,因为 hibernate 需要普通的 getter 和 setter。

    【讨论】:

      【解决方案2】:

      我认为您必须手动将已删除元素的父级设置为 null。 hibernate 中没有任何东西可以为你做这件事。您可以使用 Better Beans Binding Project 中的 Observable Collection 做得更好。然后您可以删除您的设置器,并立即反映更改。

      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);
             }
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-02
        • 2020-06-06
        • 2014-04-23
        • 2020-04-29
        • 2010-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多