是否应该避免Hibernate双向关联?

时间:2011-09-11 15:57:57

标签: java hibernate spring

在基于Spring / Hibernate的项目中,我们在两个实体之间存在一对多的关系。所需的操作是:

  • 找到孩子的父母;
  • 找到父母的孩子;
  • 删除父级时,我们还需要删除子级;
  • 大规模创造孩子们。

我们想出了两种方法来实现它。

  1. Bidirectional association:子实体有@ManyToOne列将其链接到父级,父级有@OneToMany延迟加载的子级。以上所有操作均可在模型中执行:

    child.getParent();
    parent.getChildren(); //lazy loading
    session.delete(parent); //cascade removal of the children does the trick here
    session.save(parent); //cascade persist created the children
    
  2. 单向关联:子实体的@ManyToOne列将其链接到父级,但父级没有任何子级链接。大多数操作应该在服务方法中执行:

    child.getParent(); //still in the model
    Collection<Child> findChildren(Parent parent); //service method in ChildService
    void deleteChildren(Parent parent); //service method in ChildService
    void createChild(Parent parent, ... childAttributes); //service method in ChildService invoked for each new child.
    
  3. 第一种方法似乎更容易实现(您可以重用Hibernate级联功能)但我们中的一些人认为双向关联是潜在的问题原因。

    什么应该是更好的设计选择?是否存在由双向方法创建的任何众所周知的问题,性能或设计?

4 个答案:

答案 0 :(得分:3)

如果你的查询与Hibernate在场景后面执行的查询做了同样的事情,当懒惰加载孩子时,我不会看到你通过不仅仅使用OneToMany关联获得了什么。

如果您知道自己在做什么,以及每个方法调用实体对数据库的查询意味着什么,那么映射集合应该没有任何问题。有时,遍历它们是明智的,有时最好使用即席查询来避免过多的往返数据库。关键是要了解会发生什么。

拥有一个asociation也非常有用,只是为了能够在HQL查询中浏览它,而不一定要调用相关的getter。

答案 1 :(得分:1)

@JB Nizet的回答几乎全部说明,还有一件事:看看你发布的方法调用样本,双向方法可能会使你的业务逻辑代码更具可读性。

答案 2 :(得分:0)

只要您处于延迟加载对您有用的情况,我就没有看到双向关系的真正问题。我曾经使用过使用Hibernate的Flex应用程序,当数据被序列化到客户端时,双向关系通常会导致整个数据库被下载。

YMMV

答案 3 :(得分:-1)

是, 应该尽可能避免这种情况。如果你真的认为,这是你的要求,那么只能使用双向。例如。 Emp和Dept,每个emp都有一个部门,但是部门有很多员工。 emp必须知道他的部门,但部门也应该知道他们的部门。