JPA双向关系的优缺点

6
我处于这样一种情况,需要将我的JPA单向关系更改为双向关系(一个Account实体具有Advertisements列表),以便在给定Advertisement时我可以确定它是否属于一个账户(出于安全考虑)。
似乎一个横切关注点对我的应用程序强加了一个设计决策,我不确定这是好的。
此外,我不知道使用双向关系的缺点是什么。
请问有人能够评论和建议吗?
2个回答

6

让我用一个例子来回答这个问题:

@Entity
public clas Account {

    @OneToMany(mappedBy = "account") // is mappedBy really necessary ?
    private List<Advertisements> advertisements;
}

单向关系的缺点:
缺少mappedBy属性将导致一对多的单向关系,并产生一个额外的连接表,由外键组成。这经常被视为JPA陷阱,并对数据库层面的性能产生负面影响(你需要三张表而不是两张表)。

@Entity
public clas Advertisements {

    @ManyToOne
    @JoinColumn(name="ACCOUNT_ID")
    private Account account; // is Account really necessary ?
}

双向性的缺点:
您可以从广告导航到帐户,因此在JPA方面,您可以访问单值关联路径"SELECT adv.account FROM Advertisements adv"。假设您不想,因此可能会对JPA级别的安全性产生负面影响。

非常感谢您的回复。您能详细说明双向缺点吗?您所说的“对JPA级别安全性的负面影响”是什么意思? - balteo
我强调了account对象可以通过查询封装它的Advertisements对象轻松访问。如果没有account,这根本不可能。 我只能想象一种情况,当任何原因都应该禁止在那个方向上进行访问时(即广告不应该有关于使用它们的帐户的任何知识,就像汽车不应该有关于使用它们的驾驶员的任何知识) 。 - wypieprz
好的,我明白了。非常感谢您的意见。标记为已接受。 - balteo

2
双向关系的另一个缺点是,它容易在Jackson、Hibernate JPA和/或Elasticsearch实现中陷入无限递归。在每个模型中,您将维护另一个模型的实例。例如,当您维护一个账户时,您也必须维护其广告。
假设该应用程序在繁忙的一天提供了高于中等水平的请求量。接下来发生的是,控制将开始在维护其关系的实例方法之间循环,为每个循环创建一个新的堆栈帧条目进入您的调用堆栈。每个堆栈帧都持有对方法参数、局部变量和返回地址的引用。JVM很快就会耗尽缓冲区,无法添加新的堆栈帧,您开始遇到Stackoverflow错误。
虽然并非总是如此,但如果您处理的是处理大量持久性请求的应用程序(而不是大量数据检索或数据分析请求),则双向关系的好处在面对避免持久性层上的Stackoverflow错误所需的努力和彻底性方面迅速消失。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接