在基于Spring / Hibernate的项目中,我们在两个实体之间存在一对多的关系。所需的操作是:
我们想出了两种方法来实现它。
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
单向关联:子实体的@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.
第一种方法似乎更容易实现(您可以重用Hibernate级联功能)但我们中的一些人认为双向关联是潜在的问题原因。
什么应该是更好的设计选择?是否存在由双向方法创建的任何众所周知的问题,性能或设计?
答案 0 :(得分:3)
如果你的查询与Hibernate在场景后面执行的查询做了同样的事情,当懒惰加载孩子时,我不会看到你通过不仅仅使用OneToMany关联获得了什么。
如果您知道自己在做什么,以及每个方法调用实体对数据库的查询意味着什么,那么映射集合应该没有任何问题。有时,遍历它们是明智的,有时最好使用即席查询来避免过多的往返数据库。关键是要了解会发生什么。
拥有一个asociation也非常有用,只是为了能够在HQL查询中浏览它,而不一定要调用相关的getter。
答案 1 :(得分:1)
@JB Nizet的回答几乎全部说明,还有一件事:看看你发布的方法调用样本,双向方法可能会使你的业务逻辑代码更具可读性。
答案 2 :(得分:0)
只要您处于延迟加载对您有用的情况,我就没有看到双向关系的真正问题。我曾经使用过使用Hibernate的Flex应用程序,当数据被序列化到客户端时,双向关系通常会导致整个数据库被下载。
YMMV
答案 3 :(得分:-1)
是, 应该尽可能避免这种情况。如果你真的认为,这是你的要求,那么只能使用双向。例如。 Emp和Dept,每个emp都有一个部门,但是部门有很多员工。 emp必须知道他的部门,但部门也应该知道他们的部门。