[英]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.