层次结构中 JPA 实体之间的双向关系
Posted
技术标签:
【中文标题】层次结构中 JPA 实体之间的双向关系【英文标题】:Bidirectional relationship between JPA entities in a hierarchy 【发布时间】:2020-12-07 02:47:10 【问题描述】:我正在为我的项目使用 Spring Data JPA(以 hibernate 作为提供程序)并且想知道何时需要实体之间的双向映射?
在我的用例中,我有一个 CategoryGroup
实体,它与 Department
实体具有 @ManyToOne
关系。目前,我在Department
实体中没有对应的@OneToMany
关系。从我可以理解的其他帖子来看,除非我需要通过我的实体/休眠删除,否则我可能不需要这样做。我想知道通过双向关系还能得到什么?
这是我的Department
,不包括访问者:
@Entity
@Table(name="dbo.Department")
public class Department
@Id
@Column(name="id")
private long id;
@Column(name="name")
private String name;
这是CategoryGroup
,不包括访问者:
@Entity
@Table(name="dbo.CategoryGroup")
public class CategoryGroup
@Id
@Column(name="id")
private long id;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="dept_id")
private Department department;
@Column(name="name")
private String name;
public CategoryGroup()
public CategoryGroup(String name, Department department)
this.name = name;
this.department = department;
作为后续,我的结构本质上是分层的。 Category
实体与CategoryGroup
实体具有@ManyToOne
关系,并且SubCategory
实体与Category
实体具有@ManyToOne
关系。
如果我继续在关系的父端添加双向关系映射,那么这是否意味着一旦我检索到Department
,我最终将获得整个实体层次结构直到SubCategory
?对于我的用例来说,这是不可取的。标记与FetchType.LAZY
的关系会缓解这种情况吗?
谢谢
【问题讨论】:
您的意思是您正在递归地获取数据以进行双向关系吗? @User-Upvotedon'tsayThanks 实际上,当我在Department
上添加 @OneToMany 注释时出现错误。 @OneToMany(cascade = CascadeType.ALL, mappedBy="department", orphanRemoval=true) 私有列表CategoryGroup
中的等于或哈希码。我也在读一些关于那个的东西。
【参考方案1】:
OneToMany 和 ManyToMany 关联默认是惰性的,因此在添加这些关联时不会获取整个层次结构。
通常,添加这些关联可以极大地帮助您进行查询,因为它减少了基于连接条件的显式实体连接的需要。除此之外,如果需要,您可以定义删除级联,即,如果删除部门,您可能希望删除与其关联的所有 CategoryGroup。
除此之外,可能需要从建模的角度明确分离域。您可能希望一个部门被隔离,即不知道与它相连的对象的任何信息。
【讨论】:
我目前确实将Department
作为一个单独的实体,隔离它还需要什么?我可能误解了你,但你的最后一段似乎与前两段矛盾,因为在我的情况下,Department
将是OneToMany
方面,所以从这个意义上说,它会知道与之相连的对象。
您在一般情况下询问双向关联,我试图为您提供这样做并避免它的理由。最后,它始终取决于您想要实现的目标。虽然我认为添加这些双向关联通常是一件好事,但将Set<CategoryGroup>
添加到Department
可能是不可取的,因为您引入了模型/代码依赖性。根据你想要/需要的,你可以做一个或另一个。
是否可以在不包括 Department 中的 CategoryGroup 集合的情况下建立双向关系?对于删除将在CategoryGroup
帮助中的Department
实例上声明@OnDelete(action = OnDeleteAction.CASCADE)?顺便说一句,它是一个集合还是一个列表有关系吗?我想我想知道的是,在哪种情况下它会是一个好主意,而不是在哪里不受欢迎?
就像写的一样,总的来说我认为这是一个好主意。不包括它的唯一原因是 IMO 当您想要隔离模型时(例如Department
)。 @OnDelete
只会在 Hibernate 不知道的情况下删除 DBMS 端的表行。这可能没问题,但可能会导致问题。也许应该发生更多的级联删除?也许您有一个实体侦听器,希望在移除前触发?以上是关于层次结构中 JPA 实体之间的双向关系的主要内容,如果未能解决你的问题,请参考以下文章