[英]Load many-to-many relationship and map to entity
我對 Spring Boot/Hibernate 開發還很陌生,這是我的第一個大項目。
我有一個應用程序使用 Spring Boot、Hibernate 和 Hibernate Envers 來審計一些實體。 Hibernate Envers 設置為使用 ValidityAuditStrategy。 由於 Hibernate Envers 不支持開箱即用的急切加載對多關系,我試圖找到一種方法來執行單個查詢並檢索我需要的所有數據,以避免 N+1 查詢問題,目前,正在扼殺我的表現:在我們的開發環境中需要將近 2 分鍾才能完全加載我們需要的具有所需關系的實體。
由於我需要檢索經過審核的版本,因此我無法像在應用程序的其他部分中使用的那樣利用 EntityGraph(至少在我的理解中)。
我需要解決的一種情況有 4 個實體Parameter
、 Formula
、 Value
和Variable
,它們像這樣相關(僅顯示相關部分, Value
和Variable
是實體,此處未列出)
@Entity
public class Parameter {
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "formula_id", referencedColumnName = "id", nullable = false)
private Formula formula;
}
@Entity
public class Formula {
@ManyToOne(optional = false)
@JoinColumn(name = "tag_id")
private Value tag;
@ManyToMany
@JoinTable(
name = "Formulas_Variables",
joinColumns = @JoinColumn(name = "formula_id"),
inverseJoinColumns = @JoinColumn(name = "variable_id"))
private Set<Variable> variables = new HashSet<>();
}
我試圖做的是創建一個自定義查詢和使用結果映射@NamedNativeQuery
和@SqlResultSetMapping
但是,即使休眠創造之間的關系Formula
和Value
正確,它不是建立在數組variables
場。 我使用的查詢和映射如下:
@SqlResultSetMapping(name = "Parameter.findAllByRevisionMapping", entities = {
@EntityResult(entityClass = Parameter.class, fields = {
@FieldResult(name = "id", column = "id"),
@FieldResult(name = "formula", column = "formula_id")
}),
@EntityResult(entityClass = Formula.class, fields = {
@FieldResult(name = "id", column = "formulaId"),
@FieldResult(name = "tag", column = "tag_id"),
@FieldResult(name = "variables", column = "variable_id")
}),
@EntityResult(entityClass = DomainValue.class, fields = {
@FieldResult(name = "id", column = "tag_id")
}),
@EntityResult(entityClass = Variable.class, fields = {
@FieldResult(name = "id", column = "variableId")
})
})
@NamedNativeQuery(name = "Parameter.findAllByRevision", query = "SELECT om_c_p_aud.id,\n"
+ " f_aud.id AS formulaId,\n"
+ " dv_aud.id AS tag_id,\n"
+ " fv_aud.formula_id AS formula_id,\n"
+ " v_aud.id AS variable_id,\n"
+ " v_aud.id AS variableId\n"
+ "FROM Parameters_AUD om_c_p_aud\n"
+ " LEFT OUTER JOIN Formulas_AUD f_aud\n"
+ " ON f_aud.id = om_c_p_aud.formula_id AND f_aud.REV <= ?1 AND\n"
+ " f_aud.REVTYPE <> 2 AND (f_aud.REVEND > ?1 OR\n"
+ " f_aud.REVEND IS NULL)\n"
+ " LEFT OUTER JOIN Values_AUD dv_aud\n"
+ " ON dv_aud.id = f_aud.tag_id AND dv_aud.REV <= ?1 AND\n"
+ " dv_aud.REVTYPE <> 2 AND (dv_aud.REVEND > ?1 OR\n"
+ " dv_aud.REVEND IS NULL)\n"
+ " LEFT OUTER JOIN Formulas_Variables_AUD fv_aud\n"
+ " ON fv_aud.formula_id = f_aud.id AND fv_aud.REV <= ?1 AND\n"
+ " fv_aud.REVTYPE <> 2 AND (fv_aud.REVEND > ?1 OR\n"
+ " fv_aud.REVEND IS NULL)\n"
+ " LEFT OUTER JOIN Variables_AUD v_aud\n"
+ " ON v_aud.id = fv_aud.variable_id AND v_aud.REV <= ?1 AND\n"
+ " v_aud.REVTYPE <> 2 AND (v_aud.REVEND > ?1 OR\n"
+ " v_aud.REVEND IS NULL)\n"
+ "WHERE om_c_p_aud.REV <= ?1\n"
+ " AND om_c_p_aud.REVTYPE <> 2\n"
+ " AND (om_c_p_aud.REVEND > ?1 OR\n"
+ " om_c_p_aud.REVEND IS NULL)", resultSetMapping = "Parameter.findAllByRevisionMapping")
我在調用findAllByRevision
查詢時收到的 json 對象的結果數組是這樣的
[
{
"id":1,
"formula":{
"id":52,
"tag":{
"id":20
},
"variables":null
}
},
{
"id":2,
"formula":{
"id":88,
"tag":{
"id":24
},
"variables":null
}
},
{
"id":2,
"formula":{
"id":88,
"tag":{
"id":24
},
"variables":null
}
},
{
"id":2,
"formula":{
"id":88,
"tag":{
"id":24
},
"variables":null
}
},
{
"id":2,
"formula":{
"id":88,
"tag":{
"id":24
},
"variables":null
}
},
{
"id":2,
"formula":{
"id":88,
"tag":{
"id":24
},
"variables":null
}
},
{
"id":2,
"formula":{
"id":88,
"tag":{
"id":24
},
"variables":null
}
}
]
而我期望的是
[
{
"id":1,
"formula":{
"id":52,
"tag":{
"id":20
},
"variables":[
{
"id":4
}
]
}
},
{
"id":2,
"formula":{
"id":88,
"tag":{
"id":24
},
"variables":[
{
"id":3
},
{
"id":23
},
{
"id":33
},
{
"id":34
},
{
"id":35
},
{
"id":52
}
]
}
}
]
有誰知道為什么它不創建公式 <-> 變量關系? 在類似情況下使用 EntityGraph 時,我嘗試檢查 Hibernate 創建的查詢,在我看來,它與上面顯示的查詢相同。 我無法檢查在這種情況下使用的映射(再次以我的理解)。
您應該能夠使用 HQL 為審計關聯指定連接提取。 被審計的實體就像一個普通的實體。 實體名稱通常以“_AUD”為后綴,因此如果您想查詢Parameters
的審計信息,您可以查詢Parameters_AUD
,例如:
SELECT p
FROM Parameters_AUD p
LEFT JOIN FETCH p.values
LEFT JOIN FETCH p.variables
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.