2016-01-29 103 views
0

作爲一個背景,我使用Spring Data JPA規範來動態構建查詢。規範使用JPA Criteria API。JPA Criteria API - 如何獲取「弱」集合

我認爲我的問題的核心是我需要在EclipseLink(我的提供程序)不支持的表上執行Right Join。

舉個簡單的例子,讓我們假設 -

TableA  TableB 
-------- -------- 
id (pk)  id (pk) 
aField  aField 
bField  table_a_id 

@Entity 
@Table(name = "TableA") 
public class TableAEntity{ 

private String id; 
private String aField; 
private String bField; 

@OneToMany(mappedBy = "tableA", , fetch=FetchType.EAGER) 
private Set<TableBEntity> tableBSet; 
} 



@Entity 
@Table(name = "TableB") 
public class TableBEntity{ 

private String id; 
private String aField; 

@ManyToOne 
@JoinColumn(name = "table_a_id", referencedColumnName = "id") 
TableAEntity tableA; 
} 

我需要能夠在不導致N + 1個查詢來獲取tableBSet集合。我已經在EclipseLink中嘗試了@BatchFetch和@JoinFetch註解,但沒有獲得肯定的結果。我已經使用性判據兩個根並添加試圖 -

builder.equal(tableARoot.get(TableAEntity_.id), 
tableBRoot.get(TableBEntity_.tableA).get(TableAEntity_.id)) 

作爲一種嘗試手動執行權在SQL加入,但不工作或者。

踢球者正在改變關係的強烈一面不是一種選擇,因爲我需要能夠做到相反。我有兩個使用這些實體的API,它需要返回兩種情況下與父代相關的設置或單個實體。

我正在使用的設計比每個實體的多重關係都要複雜得多,而且需要根據API接收的某些參數獲取大部分集合。

在這一點上,我被賦予了所選擇的框架,並且需要使用Spring Data Specifications(使用JPA Criteria API)進行高效工作。

我是Criteria API的新手,我已經閱讀了我所能做的一切,但一直沒有能夠實現一個解決方案,即在沒有N + 1查詢的情況下獲取弱集合。我覺得梳根是唯一的方法(我知道這不是很好,因爲我最終會得到一個笛卡爾產品),但我無法完成這項工作。 fetch()和join()似乎沒有幫助,因爲我只能做左連接。

什麼是最好的方式去做這個或我試圖做太多與Criteria API?

+1

在標準API,就像在JPQL,避免了N + 1點的問題,你用一個fetch連接:http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/FetchParent .html:'tableARoot.fetch(TableAEntity_.tableBSet)'。 –

+1

爲什麼@JoinFetch標註不能正確工作?你的查詢是什麼? – Chris

+0

我誤解了真正的問題 - 我認爲它仍然生成N + 1的原因是因爲實體A中的方法導致實體B再次查詢表A.把@JoinFetch放在那個關係上解決了這個問題。我忽略的是還有一個表C被加入,所以它可以在WHERE中使用。在JOIN和參數中的某處,它只導致A中的記錄返回B中的對應記錄,並且當我使用tableARoot.fetch(TableAEntity_.tableBSet)時,記錄也在C中具有相應的記錄。仍在追蹤那個罪魁禍首。 – DSS

回答

0

@JoinFetch或root.fetch()是正確的方法。我分頁的結果,這使得看起來好像數據沒有被返回,因爲多個表的產品中有重複的行。我必須創建一個自定義分頁,以便通過請求頁面的ID查詢來解決此問題。