作爲一個背景,我使用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?
在標準API,就像在JPQL,避免了N + 1點的問題,你用一個fetch連接:http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/FetchParent .html:'tableARoot.fetch(TableAEntity_.tableBSet)'。 –
爲什麼@JoinFetch標註不能正確工作?你的查詢是什麼? – Chris
我誤解了真正的問題 - 我認爲它仍然生成N + 1的原因是因爲實體A中的方法導致實體B再次查詢表A.把@JoinFetch放在那個關係上解決了這個問題。我忽略的是還有一個表C被加入,所以它可以在WHERE中使用。在JOIN和參數中的某處,它只導致A中的記錄返回B中的對應記錄,並且當我使用tableARoot.fetch(TableAEntity_.tableBSet)時,記錄也在C中具有相應的記錄。仍在追蹤那個罪魁禍首。 – DSS