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

VB_*_*VB_ 58 hibernate jpa lazy-loading one-to-one

我遇到的问题是一对一的延迟加载在休眠中不起作用.我已经解决了,但仍然没有正确理解会发生什么.

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

@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;
}
Run Code Online (Sandbox Code Playgroud)

但是:如果我添加optional=falseOneToOne关系,延迟加载工作正常!

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

问题/恳求:请向我解释一下optional=false注释如何帮助实现延迟加载.

PS我读过帖子post1post2,并明白为什么简单的OneToOne不能偷懒,但我仍然无法掌握optional=false魔法.

JB *_*zet 84

如果关联是可选的,则Hibernate无法在不发出查询的情况下知道给定人员是否存在地址.所以它不能用代理填充地址字段,因为可能没有引用该人的地址,并且它不能用null填充它,因为可能有一个地址引用该人.

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

  • optional = false表示...地址不是可选的.所以这是强制性的.因此将其设置为null会引发异常.这是非常期待的. (4认同)
  • 除了它实际上不会延迟加载关联之外,它是可能的.也可以使用LazyToOne(NO_PROXY)并在构建时使用字节码IIRC,但我对此有不好的经历.如果关联是可选的,您最好使用专用连接列. (3认同)

sen*_*982 9

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

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

最后一个解决方案是使用运行时字节码检测,但它只适用于那些在完整的JEE环境中使用Hibernate作为JPA提供者的人(在这种情况下设置" hibernate.ejb.use_class_enhancer"为true应该可以做到这一点:实体管理器配置)或者使用Hibernate Spring配置为执行运行时编织(在某些较旧的应用程序服务器上可能很难实现).在这种情况下@LazyToOne(LazyToOneOption.NO_PROXY),还需要注释.