Hibernate JPA @OneToOne延迟加载

时间:2015-11-05 09:59:14

标签: java hibernate jpa lazy-loading one-to-one

我正在尝试@OneToOne关联LAZY,默认为EAGER

我可以想到两个原因:
1)假@OneToOne@ManyToOne 2)在owner表中使用外键列,然后使用fetch type作为LAZY

任何人都可以指出上述策略的优点/缺点。另外,请告诉我是否有其他更好的解决方案。

1 个答案:

答案 0 :(得分:0)

更正确,更干净的解决方案是选项2 - 您不希望仅修改模型以指示基础ORM框架如何加载数据,除非绝对必要。但是,有些情况下这不是开箱即用的,你必须调整JPA才能真正启用LAZY行为,或者选择1(但是,选项1应该使用@OneToMany而不是{{1 }})。

我将解释并试图揭开选项2的神秘面纱 - 即。 LAZY加载@ManyToOne@OneToOne,它将引用映射到单个实体(不是集合)。例如:

@Entity 公共类Main {   @OneToOne(fetch = FetchType.LAZY)   私立中学; }

hibernate对延迟加载的方式是,它使用与类@ManyToOne相同的方法创建 proxy 对象,但仅限于{{1} }字段集和所有其他数据字段为空。当您第一次调用此对象上的任何方法时,数据将加载到新的Secondary对象中,并转发方法调用。与EAGER加载的区别不仅在于数据仅在需要时才加载,而且即使在加载数据之后,@IdSecondary实体之间也总会存在中间对象。如果可以创建Main的子类(如果不是最终的),则只能通过JPA完成此操作。

实现LAZY加载的另一种方法是修改原始Secondary类,将数据加载代码注入到每个方法中,这样就不需要代理它。实际上,代理对象的功能被合并到原始类的代码中。这称为 weaving (或字节码检测),可以在编译期间完成,甚至可以在运行时通过特殊的类加载器或附加的java代理完成。在比较执行效率时,遵循不等式:代理比动态编织慢于静态编织。因此挥动是一种优化。虽然,在现实世界中,你很少关心减速是微不足道的。

通常,如果您通过Secondary注释注入Secondary作为Java EE资源,JPA会为您执行所有代理/编织,因此LAZY加载始终有效。但是,如果您手动创建EntityManager,例如EntityManager,那么您可能需要启用编织。