带有列表的 Hibernate CRUD

Hibernate CRUD with lists

如果我有实体:

  1. 实体 1 与实体 2 有列表;
  2. Entity2 与 Entity3 有列表;
  3. Entity3 与 Entity4 有列表;

当我在数据库中添加新的 Entity4 时,我的代码中必须执行哪些操作?

  1. 只需为 Entity4 设置父项并保存 Entity4?

  1. 为 Entity4 设置父项并保存 Entity4。在列表中添加 Entity4 Entity3 并保存 Entity3。

  1. 在 Entity3 的列表中添加 Entity4 并保存 Entity3。所有实体都将更新。

其实要看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 设为私有,这样只有 Hibernate 才能在需要强制严格使用 addChild / removeChild 方法时使用它。