簡體   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