为什么休眠不能懒惰地获取@ManyToOne 和@OneToOne?
Why can't hibernate lazily fetch @ManyToOne and @OneToOne?
经过一些令人沮丧的问题和测试后,我了解到 hibernate 无法延迟获取 ToOne 关系。
据我所知,hibernate 通过将其自己的 Set 设置为代理来延迟获取 ToMany,并且当对该 Set 调用方法时,它会在执行操作之前获取数据库中的数据。很好
对于 ToOne,我看到的原因是由于该属性可以为 null(与 ToMany 不同),hibernate 必须知道它是否需要用 null 或代理填充它,而如果没有,hibernate 就无法知道查询另一个 table。由于它必须查询其他 table,因此它会同时急切地获取数据。
我觉得这很愚蠢。我可以在关系的非拥有方理解它,其中 table 中没有任何内容指示 toOne 是否已填充,但在拥有方,table 包含一个带有外键的列,它是否为 null。
为什么休眠不能查询 table 并根据该列的值将属性设置为 null 或代理?它不需要检查第二个 table,如果你的列不为空,你就知道第二个 table 有一个相应的条目(如果没有,你有完整性问题和休眠应该扔掉)。
Hibernate 的行为或多或少与您描述的一样。
在拥有方面,hibernate 支持延迟加载,只是默认情况下未启用。您需要添加它 @OneToOne(fetch = FetchType.LAZY)
但是当你有双向映射(在两个实体上)时,正如你所说,hibernate 需要查询 table 来决定空值还是代理。因此开发人员决定急切加载整个实体。无论提取类型如何。
您可以通过删除外键并仅 use same primary key vaue.
来避免这些问题
您可以在拥有方使用 @MapsId
注释来做到这一点。
@Entity
public class Owning {
@Id
private Long id;
@OneToOne
@MapsId
@JoinColumn(name = "id")
private Child child;
}
经过一些令人沮丧的问题和测试后,我了解到 hibernate 无法延迟获取 ToOne 关系。
据我所知,hibernate 通过将其自己的 Set 设置为代理来延迟获取 ToMany,并且当对该 Set 调用方法时,它会在执行操作之前获取数据库中的数据。很好
对于 ToOne,我看到的原因是由于该属性可以为 null(与 ToMany 不同),hibernate 必须知道它是否需要用 null 或代理填充它,而如果没有,hibernate 就无法知道查询另一个 table。由于它必须查询其他 table,因此它会同时急切地获取数据。
我觉得这很愚蠢。我可以在关系的非拥有方理解它,其中 table 中没有任何内容指示 toOne 是否已填充,但在拥有方,table 包含一个带有外键的列,它是否为 null。
为什么休眠不能查询 table 并根据该列的值将属性设置为 null 或代理?它不需要检查第二个 table,如果你的列不为空,你就知道第二个 table 有一个相应的条目(如果没有,你有完整性问题和休眠应该扔掉)。
Hibernate 的行为或多或少与您描述的一样。
在拥有方面,hibernate 支持延迟加载,只是默认情况下未启用。您需要添加它 @OneToOne(fetch = FetchType.LAZY)
但是当你有双向映射(在两个实体上)时,正如你所说,hibernate 需要查询 table 来决定空值还是代理。因此开发人员决定急切加载整个实体。无论提取类型如何。
您可以通过删除外键并仅 use same primary key vaue.
来避免这些问题您可以在拥有方使用 @MapsId
注释来做到这一点。
@Entity
public class Owning {
@Id
private Long id;
@OneToOne
@MapsId
@JoinColumn(name = "id")
private Child child;
}