为什么不能休眠懒惰地获取@ManyToOne 和@OneToOne?

elc*_*cye 5 java hibernate lazy-loading one-to-one

在经历了一些令人沮丧的问题和测试之后,我了解到 hibernate 不能懒惰地获取 ToOne 关系。

从我读过的内容来看,hibernate 通过将自己的 Set 设置为代理来延迟获取 ToMany,并且当在该 Set 上调用方法时,它会在执行操作之前获取数据库中的数据。美好的。

对于 ToOne,我看到的原因是,由于属性可以为 null(与 ToMany 不同),hibernate 必须知道它是否需要使用 null 或代理填充它,并且 hibernate 在不查询另一个表的情况下无法知道这一点。由于它必须查询其他表,因此它同时急切地获取数据。

我觉得这很愚蠢。我可以在关系的非拥有方理解它,表中没有任何内容指示是否填充了 toOne,但在拥有方,表包含一个带有外键的列,该列要么为空,要么不为空。

为什么不能休眠查询表并根据该列的值将属性设置为 null 或代理?它不需要检查第二个表,如果你的列不为空,你就知道第二个表有一个相应的条目(如果没有,你有完整性问题,hibernate 应该抛出)。

小智 1

Hibernate 的行为或多或少像您所描述的那样。

在拥有方,hibernate 支持延迟加载,只是默认情况下未启用。你需要添加它@OneToOne(fetch = FetchType.LAZY)

但是,当您有双向映射(在两个实体上)时,正如您所说,hibernate 需要查询表来决定 null 或代理。因此开发人员决定立即加载整个实体。与获取类型无关。

您可以通过摆脱外键并仅使用相同的主键 vaue来避免这些问题。

您可以通过@MapsId拥有方的注释来做到这一点。

@Entity
public class Owning {
 
    @Id
    private Long id;
 
    @OneToOne
    @MapsId
    @JoinColumn(name = "id")
    private Child child;
 
}
Run Code Online (Sandbox Code Playgroud)