我正在嘗試使用JPQL生成單個 SQL 陳述句來獲取多個不同的物體,所有物體都使用外鍵相互鏈接。
模型
該模型如下所示:
@Entity
@Table(name = "mainentity")
@Data
@IdClass(MainEntityPrimaryKey.class)
public class MainEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true)
@JoinColumns({
@JoinColumn(name = "foo", referencedColumnName = "foo"),
@JoinColumn(name = "bar", referencedColumnName = "bar")
})
private List<SubEntity> subs;
}
@Entity
@Table(name = "subentity")
@Data
@IdClass(SubEntityPrimaryKey.class)
public class SubEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "first_possibility_id", referencedColumnName = "first_possibility")
private FirstPossibility firstPossibility;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "second_possibility_id", referencedColumnName = "second_possibility")
private SecondPossibility secondPossibility;
}
@Entity
@Table(name = "firstpossibility")
@Data
public class FirstPossibility {
@Id
@Column(name = "first_possibility_id", nullable = false, updatable = false)
private String id;
@Column
private String something;
}
@Entity
@Table(name = "secondpossibility")
@Data
public class SecondPossibility {
@Id
@Column(name = "second_possibility_id", nullable = false, updatable = false)
private String id;
@Column
private String stuff;
}
ASubEntity永遠不會同時鏈接aFirstPossibility和SecondPossibility。
存盤庫
Spring-Data 介面:
public interface MainEntityCRUDRepository extends CrudRepository<MainEntity, MainEntityPrimaryKey> {
@Query("SELECT main FROM MainEntity main WHERE CONCAT(main.foo, '~', main.bar) IN :ids")
List<MainEntity> getAllMainWithConcatenatedIds(@Param("ids") Collection<String> ids);
}
當前狀態
事實上,它MainEntity在對資料庫的一次呼叫中正確獲取所有內容(我可以看到系結正確發生在spring.jpa.show-sql=true屬性上),但沒有任何SubEntity.
該SubEntityGET拿來當事情結束了試圖在稍后訪問他們的代碼,并且還最終獲取的First或Second物體。所有這一切,每個物體都有單獨的資料庫呼叫(這是我們想要避免的性能方面的東西)。
重要提示:我們EclipseLink用作我們的 JPA 提供程式。
uj5u.com熱心網友回復:
感謝 Chris 的評論和幫助,我找到了這個解決方案:
public interface MainEntityCRUDRepository extends CrudRepository<MainEntity, MainEntityPrimaryKey> {
@QueryHints({
@QueryHint(name = org.eclipse.persistence.config.QueryHints.LEFT_FETCH, value = "main.subs.firstPossibility"),
@QueryHint(name = org.eclipse.persistence.config.QueryHints.LEFT_FETCH, value = "main.subs.secondPossibility")
})
@Query("SELECT main FROM MainEntity main WHERE CONCAT(main.foo, '~', main.bar) IN :ids")
List<MainEntity> getAllMainWithConcatenatedIds(@Param("ids") Collection<String> ids);
}
生成的 SQL 如下所示:
SELECT *
FROM mainentity t1
LEFT OUTER JOIN subentity t0 ON ((t0.foo = t1.foo) AND (t0.bar = t1.bar))
LEFT OUTER JOIN firstpossibility t2 ON (t2.id = t0.first_possibility_id)
LEFT OUTER JOIN secondpossibility t3 ON (t3.id = t0.second_possibility_id)
WHERE (t1.foo || '~' || t1.bar IN (...))
你注意到沒有JOIN FETCH main.subs sub在@Query:由該提示導航通過暗示main.subs了。
如果添加JOIN FETCH,則結果中實際上會有重復項List。這些重復項是因為這就是 DB 實際回傳結果的方式(每個FirstPossibility和SecondPossibility找到的都會在結果集中創建一個條目。
如果您想使用QueryHints.BATCH代替,則JOIN FETCH main.subs sub實際上需要使用 ,但您不會通過單個資料庫呼叫回傳整個結果:SELECT將發出多個陳述句。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/363963.html
上一篇:SpringBoot:預期的json回應,獲取XML回應
下一篇:spring-data-多個DB:NoUniqueBeanDefinitionException沒有可用的“TransactionManager”型別的合格bean
