具有共享主键的OneToOne关系生成n + 1个选择;任何解决方法?

具有共享主键的OneToOne关系生成n + 1个选择;任何解决方法?,第1张

具有共享主键的OneToOne关系生成n + 1个选择;任何解决方法?

想象一下关系数据库中的2个表,例如Person和Billing。这些实体之间定义了一个(非强制性的)OneToOne关联

从概念上讲,默认情况下对于非强制性的OneToOne不可能进行延迟获取,Hibernate必须访问数据库才能知道关联是否

null
存在。来自这个旧的Wiki页面的更多详细信息:

关于延迟加载(一对一)的一些说明

[…]

现在考虑我们的B类与C具有一对一关联

class B {    private C cee;    public C getCee() {        return cee;    }    public void setCee(C cee) {        this.cee = cee;    }}class C {    // Not important really}

加载B之后,您可以调用

getCee()
获得C。但是,看,这
getCee()
是YOUR类的方法,并且Hibernate无法对其进行控制。Hibernate不知道何时有人要打电话
getCee()
。这意味着Hibernate
cee
在从数据库加载B时必须将一个适当的值添加到“ ”属性中。如果启用了proxy
C
,则Hibernate可以放置一个C代理对象,该对象尚未加载,但在有人使用它时将被加载。这会导致的延迟加载
one-to-one


但是现在想象一下您的

B
对象可能有关联
C
constrained="false"
),也可能没有关联()。
没有
getCee()
特定的
B
时候应该返回什么
C
?空值。但是请记住,Hibernate必须在设置时立即设置“ cee”的正确值
B

(因为它不知道何时有人会呼叫
getCee()
)。代理服务器在这里没有帮助,因为代理服务器本身已经存在于非null对象中。

简历: 如果B- >
C映射是必需的(

constrained=true
),则Hibernate将对C使用代理,从而导致延迟初始化。但是,如果允许B不带C,则Hibernate只需在加载B时检查C的存在。但是SELECT来检查存在性的SELECT效率低下,因为同一SELECT可能不仅检查存在性,而且还加载了整个对象。因此,懒惰的负载消失了

因此,不可能…默认情况下。

有没有针对这种潜在性能灾难的解决方法(除了根本不使用共享主键之外)?谢谢您的所有想法。

问题不是共享主键,有或没有共享主键,您都会明白的,问题是 空的 OneToOne。

第一种选择 :使用字节码检测(请参阅下面的文档参考)和 无代理 获取:

@oneToOne( fetch = FetchType.LAZY )@org.hibernate.annotations.LazyToOne(org.hibernate.annotations.LazyToOneOption.NO_PROXY)

第二种选择
:使用假货

ManyToOne(fetch=FetchType.LAZY)
。那可能是最简单的解决方案(据我所知,是推荐的解决方案)。但是我没有使用共享PK对此进行测试。

第三种选择 :急于使用加载结算信息

join fetch

参考文献
  • hibernate参考指南
    • 19.1.3。单端关联代理
    • 19.1.7。使用懒惰的属性获取
  • 旧的Hibernate常见问题解答
    • 如何将一对一关系设置为惰性关系?
  • hibernateWiki
    • 关于延迟加载(一对一)的一些说明


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5124605.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-17
下一篇 2022-11-17

发表评论

登录后才能评论

评论列表(0条)

保存