Hibernate CRUD与列表

时间:2016-10-11 09:29:10

标签: java hibernate hibernate-mapping

如果我有实体:

  1. Entity1包含Entity2的列表;
  2. Entity2包含Entity3的列表;
  3. Entity3包含Entity4;
  4. 的列表

    当我在DB中添加新的Entity4时,我的代码中的操作是什么?

    1. 只需为Entity4设置父级并保存Entity4?
      1. 为Entity4设置父级并保存Entity4。在列表中添加Entity4 Entity3并保存Entity3。
        1. 在Entity3列表中添加Entity4并保存Entity3。并且所有实体都将更新。

1 个答案:

答案 0 :(得分:0)

这实际取决于Entity3维护的列表是否设置为级联操作,例如PERSISTMERGEDELETE

如果列表配置为级联,那么您需要做的就是:

  • 设置Entity4的父级。
  • Entity4添加到其父级列表中并合并修改后的父级。

如果未配置级联,则您需要执行以下操作:

  • 设置Entity4的父级。
  • 保留新创建的实例Entity4
  • Entity4添加到其父级列表中并合并修改后的父级。

现在您可能会问为什么Entity4的父实体必须更新其列表并随后在两种情况下合并?

这是为了确保关联的两端都正确更新并正确指向彼此。它很可能是因为关联的父端已经加载到持久化上下文中,所以将子项添加到数据库不会刷新并且对已经加载的实体可见,除非它已刷新。在这种情况下,最简单的解决方案是始终正确地修改双方。

public class ParentEntity {

  // add child to the parent entity, maintains association
  public void addChild(ChildEntity child) {
    if ( child.getParent() != null ) { 
      child.getParent().removeChild( child );
    }
    child.setParent( this );
    children.add( child );
  }

  // remove child from parent, disassociates association
  public void removeChild(ChildEntity child) {
    if ( this.equals( child.getParent() ) ) {
      child.setParent( null );
      children.remove( child );
    }
  }
}

我通常发现在我的域模型上公开上述辅助方法很有帮助,这样我的代码就不需要关心需要维护的关联。我也可能将父实体列表的setter设为private,这样只有Hibernate才能使用它来强制严格使用addChild / removeChild方法。