繁体   English   中英

延迟加载多对多实体时,为什么会收到N + 1个选择查询

[英]Why do I get N+1 select queries when lazy loading many-to-many entities

我期望仅获得一个sql查询,但遇到N + 1选择陷阱。 我真的不明白为什么。 这是详细的问题:

我有一个实体“ PlayerRef”:

@Entity
@Table(name = "player_ref")
public class PlayerRef {

  //constructor etc...

  @OptimisticLock(excluded = true)
  @LazyCollection(LazyCollectionOption.TRUE)
  @ManyToMany(fetch = FetchType.LAZY, mappedBy = "playerRefs")
  public Set<Player> getPlayers() {
    return players;
  }

}

和一个班级球员:

@Entity
@Table(name = "player")
public class Player {

  //constructor etc...

  @OptimisticLock(excluded = true)
  @LazyCollection(LazyCollectionOption.TRUE)
  @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name="cr_player_ref_player", 
      joinColumns = {
        @JoinColumn(name="player_id", unique = true)           
      }
      ,inverseJoinColumns = {
        @JoinColumn(name="player_ref_id")
      }     
    )
  private Set<PlayerRef> getPlayerRefs() {
    return this.playerRefs;
  }
}

现在,在我的程序中,我使用以下HQL查询来获取所有playerRef实体:

Query playerRefQ = session.createQuery("select playerRef from PlayerRef playerRef ")
  .setReadOnly(true); 
playerRefQ.setParameter("sport", sport);
@SuppressWarnings("unchecked")
List<PlayerRef> allPlayerRefs = playerRefQ.list();

这将导致N + 1个Select语句:

1)

select
    playerref0_.id as id1_21_0_,
    ... 
from
    player_ref playerref0_ 

N次)

select
    players0_.player_ref_id as player_r2_21_0_,
    players0_.player_id as player_i1_34_0_,
    player1_.id as id1_19_1_,
    ...
from
    cr_player_ref_player players0_ 
inner join
    betdata.player player1_ 
        on players0_.player_id=player1_.id 
where
    players0_.player_ref_id=?

(再次)这是非常出乎意料的,因为我认为该集合是延迟加载的,并且每个playerRef的播放器集都应该是休眠代理。

谁知道我真的只能加载playerRef实体,而又不加载关联的玩家吗? 对于我的用例,我需要所有playerRefs,但不需要关联的players。

在我的较早问题中,有人建议,可以某种方式引用引用关联实体的方式重写playerRef或Player的toString()方法。 不是这种情况。 N + 1查询是在访问所有playerRef实体列表时发生的。

笔记:

  1. 这是为什么会导致非延迟获取和N + 1选择语句的后续问题

  2. 同样没有解决方案的类似问题在这里: 如何在休眠状态下延迟加载多对多集合?

为了解决该问题,您需要使用“批处理大小”和“提取”模式,这里的参考链接将告诉您如何克服N + 1选择问题

希望这会有所帮助

http://www.mkyong.com/hibernate/hibernate-fetching-strategies-examples/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM