Hibernate: 一对一的延迟加载,可选 = false

我面临的问题是,一对一的延迟加载不工作在冬眠。我有 已经解决了,但仍然 不要适当 明白发生什么。

我的代码(延迟加载在这里不起作用,当我提取 Person-Address 时也会提取) :

@Entity
public class Person{


@Id
@SequenceGenerator(name = "person_sequence", sequenceName = "sq_person")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "person_sequence")
@Column(name = "id")
private long personID;


@OneToOne(mappedBy="person", cascade=CascadeType.ALL, fetch = FetchType.LAZY)
private Adress address;
//.. getters, setters
}


@Entity
public class Address {


@Id
@Column(name="id", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="person"))
private long personID;


@PrimaryKeyJoinColumn
@OneToOne
private FileInfo person;
}

但是 : 如果我在 OneToOne 关系中添加 optional=false,延迟加载 没问题

@OneToOne(mappedBy="person", cascade=CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
private Adress address;

问题/条约: 请解释一下 optional=false注释是如何帮助实现延迟加载的。

我读过 邮政编码1邮政编码2的文章,明白了为什么简单的 OneToOne 不能偷懒,但我还是不能掌握 optional=false的魔力。

61023 次浏览

如果关联是可选的,那么 Hibernate 无法在不发出查询的情况下知道给定人员的地址是否存在。所以它不能用代理来填充地址字段,因为可能没有地址指向这个人,也不能用 null来填充,因为可能有地址指向这个人。

当您强制关联(即 optional=false)时,它信任您并假设存在一个地址,因为关联是强制的。因此,它直接使用代理填充地址字段,并且知道有一个地址指向这个人。

最简单的就是假装一对多的关系。这将工作,因为集合的延迟加载比单个可空属性的延迟加载容易得多,但是如果您使用复杂的 JPQL/HQL 查询,通常这种解决方案是非常不方便的。

另一种是使用构建时字节码检测。有关详细信息,请阅读 Hibernate 文档: 19.1.7。使用惰性属性获取。请记住,在这种情况下,您必须将 @LazyToOne(LazyToOneOption.NO_PROXY)注释添加到一对一关系中,以使其变得懒惰。设置抓取到 LAZY 是不够的。

最后一个解决方案是使用运行时字节码插装,但它只适用于那些在成熟的 JEE 环境中使用 Hibernate 作为 JPA 提供者的人(在这种情况下,将“ hibernate.ejb.use_class_enhancer”设置为 true 应该可以达到这个目的: 实体管理器配置)或者使用 Hibernate 和配置了 Spring 的 Spring 来进行运行时编织(这在一些较老的应用服务器上可能很难实现)。在这种情况下,还需要 @LazyToOne(LazyToOneOption.NO_PROXY)注释。