我正在尝试@OneToOne
关联LAZY
,默认为EAGER
。
我可以想到两个原因:
1)假@OneToOne
为@ManyToOne
2)在owner表中使用外键列,然后使用fetch type作为LAZY
。
任何人都可以指出上述策略的优点/缺点。另外,请告诉我是否有其他更好的解决方案。
答案 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加载的区别不仅在于数据仅在需要时才加载,而且即使在加载数据之后,@Id
和Secondary
实体之间也总会存在中间对象。如果可以创建Main
的子类(如果不是最终的),则只能通过JPA完成此操作。
实现LAZY加载的另一种方法是修改原始Secondary
类,将数据加载代码注入到每个方法中,这样就不需要代理它。实际上,代理对象的功能被合并到原始类的代码中。这称为 weaving (或字节码检测),可以在编译期间完成,甚至可以在运行时通过特殊的类加载器或附加的java代理完成。在比较执行效率时,遵循不等式:代理比动态编织慢于静态编织。因此挥动是一种优化。虽然,在现实世界中,你很少关心减速是微不足道的。
通常,如果您通过Secondary
注释注入Secondary
作为Java EE资源,JPA会为您执行所有代理/编织,因此LAZY加载始终有效。但是,如果您手动创建EntityManager,例如EntityManager
,那么您可能需要启用编织。