Hibernate.initialize()的工作原理

我知道在会话之外使用延迟加载对象/集合,我们执行Hibernate.initialize(Object obj)以便初始化作为参数传递给initialize()方法的对象,并且可以在会话范围之外使用。

但我无法理解这是如何工作的。 我的意思是,如果我们这样做,那么我们最终会有急切的提取,所以为什么我们在配置中做了懒惰,最终在运行时进行了急切的提取。

换句话说,我想知道使用Hibernate.initialize()eagerly加载该对象之间的区别。

我弄错了还是错过了什么?

不同之处在于应用范围。

使集合关联变得懒惰的原因是,如果您不真正需要它,则每次加载父对象时都要避免加载集合。

如果您正在懒惰加载集合,但是对于特定用途,您需要确保在会话关闭之前已加载集合,您可以使用Hibernate.initialize(Object obj)

如果你实际上总是需要加载集合,你应该确实加载它。 但在大多数软件中,情况并非如此。

请考虑以下示例:

我有一个实体LoanApplication(在这种情况下是一个非常重的对象),它内部有各种字段(也可能很大)。 例如,考虑LoanApplication中的SubLoan字段。

 @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "application_fk") @Index(name = "appl_fk_idx_subloansLoanApp") private Set subLoans; 

在此示例中,FetchType为LAZY。 现在,如果在执行某些操作时某些控制器的方法中遇到LoanApplication,则除非您希望使用它,否则subLoans集最初将为null。 在这种情况下,你使用Hibernate.initialize如下:

 Hibernate.initialize(loanApplication.getSubLoans()); 

这有助于主要提高性能,因为每次检索LoanApplication时,除非您真的需要,否则大量对象即’subLoan’最初将为空。

考虑一下@Don Ruby的回答

下一个区别是Hibernate.initialize生成并执行其他sql以获取数据。 因此,您可以在会话结束后使用它。 当您在实体中使用Eager fetch时,它总是在数据库中查找数据(在连接会话下)时获取该集合,而不是在它之后。

实际上,如果你使用EAGER,当你有大量的collections时,它确实会影响你的表现。 因此,在使用Hibernate.initialize这样的情况下,这是一个好主意。

看看这个: Hibernate Lazy Fetch vs Eager Fetch Type

考虑你有一个表可能与其他4个表有关系。 在这种情况下,如果您使用eager,那么将在每次获取操作中获取所有四个相关表中的所有对应关系。

但是考虑到您可能需要相关表中只有一个表的数据,因此在这种情况下,您只能获取所需的关系,而不是使用Hibernate.initialize工具提取整个四个相关表的数据。 。