Hibernate Cascade: отмените ссылку на родительский PK в дочерней таблице, не удаляя дочерний объект - PullRequest
0 голосов
/ 15 июля 2011

Если родительский объект начинается со списка из 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;
  }
}

Это решение похоже, но я не удаляю Parentвместо этого я удаляю дочерний элемент из списка:

каскад гибернации - обновите дочерний элемент до нуля

Ответы [ 2 ]

0 голосов
/ 15 июля 2011

Если у вас нет ограничения not-null на родительское поле FK в дочерней таблице, вы можете просто установить parent в null и сохранить дочернего.

Я написал бы следующий метод:

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

Я бы с осторожностью переписал метод setChildren, так как для режима гибернации нужны простые методы получения и установки.

0 голосов
/ 15 июля 2011

Я думаю, вам придется вручную установить родителя удаленного элемента в нуль. В спящем режиме нет ничего, что могло бы сделать это для вас. Вы можете добиться большего успеха, используя Observable Collection из проекта Better Beans Binding Project. Затем вы можете удалить свой сеттер и немедленно отразить изменения.

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);
       }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...