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

我遇到了一对一延迟加载在hibernate中无法正常工作的问题。 我已经解决了 ,但仍然没有正确理解会发生什么。

我的代码( 懒加载不工作在这里 ,当我拉人 – 地址也被提取):

@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; 

Question / Entreaty:请向我解释如何optional=false注释有助于实现延迟加载。

PS我读过postpost1和post2 ,并明白为什么简单的OneToOne不能懒惰,但我仍然不能掌握optional=false魔术。

如果关联是可选的,Hibernate无法知道给定的人是否存在地址,而不发出查询。 所以它不能用代理填充地址字段,因为可能没有地址引用这个人,也不能用null填充它,因为可能有一个引用这个人的地址。

当你使关联成为强制性的(即可optional=false )时,它信任你,并假定存在一个地址,因为这个关联是强制性的。 所以它直接使用代理填充地址字段,知道有一个地址引用这个人。

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

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

最后一个解决scheme是使用运行时字节码检测,但只适用于那些在成熟的JEE环境中将Hibernate用作JPA提供程序的人(在这种情况下,将“ hibernate.ejb.use_class_enhancer ”设置为true应该这样做:实体pipe理器configuration)或者使用Springconfiguration的Hibernate来执行运行时编织(这在一些较旧的应用程序服务器上可能很难实现)。 在这种情况下@LazyToOne(LazyToOneOption.NO_PROXY)注释也是必需的。