Java 在冬眠中急切地取回是什么意思

Java 在冬眠中急切地取回是什么意思,java,spring,hibernate,Java,Spring,Hibernate,我正在读Prospring3的书,书中概述了如何同时使用Spring和Hibernate。但是,我看到了这样一句话:“你可以急切地把协会请来。”。我的问题是: 在Hibernate中急切地获取关联的真正含义是什么?这会对Hibernate中的查询性能产生什么影响,甚至会产生什么影响?急切地获取意味着从数据库中查找父实体时,会同时查找所有关联实体 延迟抓取(相反)意味着只查找父实体自己的字段。关联实体由代理填充,如果/当引用它们时,代理将从数据库中查找它们 因此,查询性能的主要区别在于查找关联实体

我正在读Prospring3的书,书中概述了如何同时使用Spring和Hibernate。但是,我看到了这样一句话:“你可以急切地把协会请来。”。我的问题是:


在Hibernate中急切地获取关联的真正含义是什么?这会对Hibernate中的查询性能产生什么影响,甚至会产生什么影响?

急切地获取意味着从数据库中查找父实体时,会同时查找所有关联实体


延迟抓取(相反)意味着只查找父实体自己的字段。关联实体由代理填充,如果/当引用它们时,代理将从数据库中查找它们

因此,查询性能的主要区别在于查找关联实体的时间。对于急切抓取,这将始终在加载父对象的同时发生,而对于惰性抓取,这将在稍后发生(可能永远不会发生)


由于随需应变的行为,延迟加载听起来是明显的赢家,但是有几个警告需要记住。首先,你的关系范围可能很难确定。看起来像普通实体对象的对象实际上有一个嵌入式数据库连接,可以在任何时候由“普通”getter方法(或者更糟的是由这些方法的客户端)调用。知道何时可以关闭连接或将其返回池几乎是不可能的。类似地,当“简单”对象在调试期间没有设置其字段时,这种行为可能会导致混乱,或者当您只是迭代从所述“简单”对象上的getter方法返回的集合时,抛出SQL异常

此外,如果关联实体与父实体分开加载,则聚合性能可能会更差。另一个SQL往返过程会带来额外的开销,但更重要的是,数据库不能重用联接等中的现有查找。在始终使用关联实体的情况下,即时获取可能更快、更容易支持


根据经验,延迟加载应该是一种经过仔细考虑的优化,在很可能不使用关系的情况下。

快速抓取意味着从数据库中查找父实体时,同时查找所有关联实体


延迟抓取(相反)意味着只查找父实体自己的字段。关联实体由代理填充,如果/当引用它们时,代理将从数据库中查找它们

因此,查询性能的主要区别在于查找关联实体的时间。对于急切抓取,这将始终在加载父对象的同时发生,而对于惰性抓取,这将在稍后发生(可能永远不会发生)


由于随需应变的行为,延迟加载听起来是明显的赢家,但是有几个警告需要记住。首先,你的关系范围可能很难确定。看起来像普通实体对象的对象实际上有一个嵌入式数据库连接,可以在任何时候由“普通”getter方法(或者更糟的是由这些方法的客户端)调用。知道何时可以关闭连接或将其返回池几乎是不可能的。类似地,当“简单”对象在调试期间没有设置其字段时,这种行为可能会导致混乱,或者当您只是迭代从所述“简单”对象上的getter方法返回的集合时,抛出SQL异常

此外,如果关联实体与父实体分开加载,则聚合性能可能会更差。另一个SQL往返过程会带来额外的开销,但更重要的是,数据库不能重用联接等中的现有查找。在始终使用关联实体的情况下,即时获取可能更快、更容易支持


根据经验,延迟加载应该是一种经过仔细考虑的优化,在这些情况下,关系很可能不会被使用。

让我用一个简单的例子来说明这一点:假设您正试图编写一个查询,以获取一个
用户
对象及其所有
Post
对象(一对多关系)。当您急切地抓取时,这意味着
Post
记录将与
用户
对象一起加载到持久性上下文中

如果延迟加载,则意味着Hibernate不会加载除
用户
对象之外的任何数据。在这两种情况下,Hibernate都将使用代理对象,如果您在懒惰时尝试访问
用户的
Post
s,您可能会遇到可怕的
懒散初始化异常


我的建议是,在大多数情况下,您应该将所有内容设置为延迟加载,并且可以在JPQL查询中使用
joinfetch
语法。这与
标准
API的工作方式类似。

让我用一个简单的例子来说明这一点:假设您试图编写一个查询,以获取一个
用户
对象及其所有
帖子(一对多关系)。当您急切地抓取时,这意味着
Post
记录将与
用户
对象一起加载到持久性上下文中

如果延迟加载,则意味着Hibernate不会加载除
用户
对象之外的任何数据。在这两种情况下,Hibernate都将使用代理对象,如果您在懒惰时试图访问
用户的
Post
s,您可能会遇到可怕的
懒散初始化异常