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

Hibernate 休眠:一对一延迟加载,可选=false,hibernate,jpa,lazy-loading,one-to-one,Hibernate,Jpa,Lazy Loading,One To One,我面临的问题是,一对一的延迟加载在hibernate中不起作用。我已经解决了它,但仍然没有正确理解发生了什么 我的代码(延迟加载在这里不起作用,当我提取Person时,地址也被提取): 但是:如果我在OneToOne关系中添加optional=false,则延迟加载效果良好 @OneToOne(mappedBy="person", cascade=CascadeType.ALL, optional = false, fetch = FetchType.LAZY) private Adress a

我面临的问题是,一对一的延迟加载在hibernate中不起作用。我已经解决了它,但仍然没有正确理解发生了什么

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

但是:如果我在OneToOne关系中添加
optional=false
,则延迟加载效果良好

@OneToOne(mappedBy="person", cascade=CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
private Adress address;
问题/恳求:请向我解释
optional=false
注释如何帮助实现延迟加载


p.S.我读过帖子和,理解了为什么简单的OneToOne不能偷懒,但我仍然无法理解
optional=false
的魔力。

如果关联是可选的,Hibernate就无法在不发出查询的情况下知道某个人的地址是否存在。因此,它不能用代理填充地址字段,因为可能没有引用此人的地址,也不能用
null
填充地址字段,因为可能有引用此人的地址


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

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

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


最后一种解决方案是使用运行时字节码插装,但它只适用于那些在成熟的JEE环境中使用Hibernate作为JPA提供程序的人(在这种情况下,将“
Hibernate.ejb.use_class\u enhancer
”设置为true应该做到:实体管理器配置)或者使用Hibernate和配置为执行运行时编织的Spring(在一些较旧的应用程序服务器上可能很难实现)。在这种情况下,
@LazyToOne(LazyToOneOption.NO_PROXY)
注释也是必需的。

optional=false在试图保存没有地址的人员时不起作用:“org.hibernate.PropertyValueException:notnull属性引用null或瞬时值:“optional=false意味着。。。地址不是可选的。所以这是强制性的。因此,将其设置为null会引发异常。这是意料之中的。这是可能的,只是它实际上不会延迟加载关联。也可以使用LazyToOne(无代理)并在构建时检测字节码IIRC,但我在这方面有过不好的经验。如果关联是可选的,你最好使用一个专用的连接列。是的,我已经测试过LazyToOne(NO_PROXY)并在构建时检测字节码,但和你一样(使用另一个lib HibernateJackson)经验不好。我最终决定不映射关联并在不同的DAO中分别管理表。optional=false,对我不起作用,它仍然急切地获取这些实体@OneToOne(fetch=FetchType.LAZY,mappedBy=“fundSeries”,可选=false)私有FundSeriesDetailEntity fundSeriesDetail;嘿@Volodymyr,我和你有同样的问题。我正在尝试将BLOB列与实体分离。父实体有子实体。子实体包含二进制列。父级和子级是
相同的表
,因此我使用@OneToOne关系。虽然我使用了LAZY fetchType,但它似乎不起作用。当我输入
optional=false
时,它会工作。任何解释都将不胜感激。@Emerald214对不起,那是两年前的事了。目前我正在编写JS Mobile,无法帮助youOneToOne optional=false不适用于CascadeType.PERSIST请参见:
@OneToOne(mappedBy="person", cascade=CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
private Adress address;