簡體   English   中英

它是Hibernate的有效行為嗎(JPQL查詢,OneToMany)

[英]Is it valid behavior of Hibernate (JPQL Query , OneToMany)

我有兩個實體,比如說A和B,映射如下:

public class A{
   ...
   @OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
   Set<B> bs
}

public class B{
   ...
   String someProp;
   ...
   @ManyToOne
   @JoinColumn(name = "A_ID")
   A a
}

A的某個實體實例在數據庫中具有B的兩個元素。

當我對A執行簡單查詢時:

 entityManager.createQuery("SELECT a FROM A a WHERE a.id = 1").getSingleResult();

並且一切都按預期工作,我在Set中得到了一個實例,其中有兩個B實例,但是執行查詢時:

Query query = entityManager.createQuery("SELECT a FROM A a JOIN FETCH a.bs b WHERE b.someProp= :somePropParam");
query.setParameter("somePropParam","somePropValue");
query.getResultList();

我得到了A的實例,集合中有B的一個元素(我要求的元素)。

我修改了查詢:

 entityManager.createQuery("SELECT b.a FROM B b JOIN b.a a WHERE b.someProp = :somePropParam.. more a conditions );
//.... this query works.

不應該首先查詢加載B的所有實例嗎? Hibernate是否應該執行附加查詢以全部加載?

這是預期的行為。 這是一個常見的陷阱。 方法getSingleResult返回第一行。 當然,如果有多個B,則結果集包含多個條目,但您只會得到第一個。 這似乎有點奇怪。

但是,將其視為帶有setMaxResult(1)和經典sql連接的普通查詢。 最終將得到相同的結果。 這也是為什么如果使用急切獲取,hibernate將子選擇用於子關系的原因。

如果您期望大量的子數據,請通過額外的查詢請求子數據,並避免1:n雙向映射。 父母與孩子之間的關系應該有充分的理由,因為從長遠來看,它經常會導致問題。

其他示例請考慮以下內容。 您使用查詢和setMaxResult(10)。 可以確保獲得10個父項的潛在結果集大小是無限的。 因此,休眠狀態將沒有任何機會請求正確數量的數據。 這可能會導致在不需要它的情況下獲取大量數據。

為生成的SQL:

    Query query = entityManager.createQuery("SELECT a FROM A a JOIN     FETCH a.bs b WHERE b.someProp= :somePropParam");
    query.setParameter("somePropParam","somePropValue");
    query.getResultList();

如下:

 select  /** columns from a and b **/ 
 from A a inner join A b on a.id=b.a_id 
 where b.someProp='someProperty'

根據條件(返回1行),它是正確的SQL結果IT告訴我“是的,有一個A實例滿足您所遇到的條件,這里就是您”,但是我認為擁有“ JOIN FETCH a.bs”會迫使Hiberante這樣做。即使第一個查詢未返回元素,也要盡快加載所有“ bs”集合。 我以為Hibernate執行其他查詢,例如

SELECT b。* FROM B b在哪里b.a_id =(上面的查詢返回的ID)。

在A中建立B的完整集合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM