【问题标题】:Left join fetch and prefetching左连接获取和预取
【发布时间】:2011-04-02 02:45:10
【问题描述】:

我有一个问题,当我们有像 Select DISTINCT A from A a left join fetch a.b 这样的查询时 JPA 将填充对象 A,并且与 a 为 oneToMany 关系的对象 b 将被预取。预取到底意味着什么,因为当我调试这个对象时它有空值,并且数据库中有数据,所以我假设它是一个代理对象。代理是否包含从数据库中预取的任何数据,并且仅当我实际调用 a.getB().size() 之类的方法时才会在 a.b 上填充它?

我认为如果我使用“left join fetch”我不需要调用 a.getB().size(),但如果我不这样做,对象 b 将保留为代理,然后在表示层中,如果任何对象调用b的任何属性,就会有一个空指针。

我还可以补充一点,这个 b 对象被映射为延迟加载,这就是我使用 fetch 的原因。 :) 另外,即使我使用“left join fetch”并调用 a.getB().size(),它也不会执行任何附加查询,对吗?预取将负责获取 b 的所有数据,...它只需要我调用一个方法,以便将数据从代理传输到实际对象吗?

提前感谢您的任何解释,这真的很困扰我......

【问题讨论】:

    标签: java database jpa left-join


    【解决方案1】:

    这取决于您的 JPA 实现。

    据我所知,至少在 EclipseLink 中,如果您使用连接提取,属性将始终被实例化,永远不会为空。

    【讨论】:

    • 嗨@James,我使用eclipseLink,但它不会在查询后加载值。当我调试列表时,出现以下消息“IndirectList:未实例化”。它只会在我调用它的一些方法时填充对象,我觉得这很奇怪,因为我认为使用 fetch 它会在查询后填充对象。我想在这里了解 fetch 是否仅用于优化查询,因此即使使用它,我也总是必须在之后调用某个对象的方法?
    • 不,它应该被实例化。也许包括您的查询。它不是只读查询之类的吗?
    • Select DISTINCT p from P as p left join fetch p.rub join pab.rec as rec join rec.slc as slc left join fetch slc.cts 这是查询。我不知道您所说的“只读”是什么意思。我是使用 JPA 的初学者,我还不太了解。对不起。 :( rub 是与 P 的@OneToMany 关系,rec 是与 P 的 @ManyToOne 关系,slc 是与 rec 的 @ManyToOne 关系,cts 是与 slc 的@OneToMany 关系
    【解决方案2】:

    这可能是 DISTINCT 子句的问题,因为这里你有像 A->B 这样的映射,所以在结果集中你可能有多个 A 对 B 的结果。使用 Set 集合来填充数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      相关资源
      最近更新 更多