Spring Data JPA:嵌套对象设计 - 单向?双向?

时间:2016-12-24 12:17:17

标签: hibernate rest spring-data spring-data-jpa

假设我有这样的嵌套对象:

Customer
Project
Rent
Fault
(and maybe deeper)

客户包含我必须验证的用户权限。 然后有一种更新故障的方法:

void updateFault(long faultId, String content, User user) { .. }

问题:如何从故障到客户?

  1. 选项:使用对父项的反向引用:出租故障,租到项目,项目到客户
  2. 选项:使用从故障到客户的反向引用(以及从租赁到客户等)
  3. 选项:没有反向引用,并且通过许多数据库查询(如

    )进行操作

    rent = rentRepository.findByFault(fault);

    project = projectRepository.findByRent(rent);

    customer = customerRepository.findByProject(project);

  4. 我读过我应该避免双向引用。但是,如果我有20个级别和大量数据呢?然后选项#3根本不适合。

    我在Spring MVC项目中使用Spring Data JPA。

1 个答案:

答案 0 :(得分:1)

一般情况下,您的每个选项都可能有用例,我甚至想再添加两个:

  1. 没有反向引用,只需一次加入

  2. 更改您的模型,以便有问题的反向引用成为主要参考。

  3. 让我们看一下各种方法的属性

    1. 反向引用:这基本上意味着双向映射。虽然原则上没有任何错误,但很难让它们正确,因为基本上在操纵java中的引用时你必须保持两个方向同步,这从我的经验来看很容易出错。

    2. 直接反向引用:一旦有了这些,我想这只是一个时间问题,直到您获得对Project和Rent的引用。这也会在类之间产生循环依赖关系,否则它们根本就不直接相关。这一起让你(恕我直言)有一个纠结的混乱。

    3. 级联的数据库查询这只会很慢。我这样做的唯一情况是,当我有一个非常适合我所有其他要求的模型时,我只需要在非常稀疏的情况下使用这种结构,其中性能是无关紧要的。

    4. 直接加入:与直接反向引用相比,它不会在java端创建依赖关系纠结。您必须编写自定义查询,但这应该是直截了当的。对我来说听起来像是一个合理的解决方案。

    5. 还原模型中的引用(我在这里从@Oliver Gierke窃取点数):使用您当前的建模方法,您很容易得到一个具有<的实体em>与其他一切有的关系。如果您的域名不重要,这将变得混乱。如果你有一个1:N的关系,这通常意味着N面可以为零/空,所以它实际上是可选的。此外,您通常只需要子集。像所有未完成的项目,或所有落后于计划的项目。因此,在许多情况下,以相反方向对参考进行建模是有意义的。如果您需要导航原始方向,请使用存储库。