我有類似的東西:
@Entity
public class Edge {
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(value = FetchMode.JOIN)
@JoinColumn(name = "start_node", referencedColumnName = "id")
Node start;
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(value = FetchMode.JOIN)
@JoinColumn(name = "end_node", referencedColumnName = "id")
Node end;
}
呼叫 JPA 連接器提供的 findAll() 方法,我想獲得表單的(單個)查詢:
SELECT * FROM EDGE edge, NODE start, NODE end WHERE edge.start_id = start.id AND edge.end_id = end.id
相反,該框架首先執行單個查詢以獲取所有邊,然后對節點執行多個查詢(理想情況下為一個查詢)。我是一個冬眠初學者。我認為這是一個非常普遍的問題。我找到了很多與該問題相關的材料,但沒有正確的答案。
uj5u.com熱心網友回復:
簡而言之,JPAFetchMode.JOIN默認忽略 Hibernate 。這樣做的原因是 JPA 懶惰地獲取物體(僅在您需要它時,例??如當您呼叫時getStart())。因此,應用程式僅在您需要時才保留資源。
Eager fetching通常是一個糟糕的選擇,應該避免,除非你真的需要。我建議閱讀此執行緒,因為它列出了與此相關的許多閱讀材料。
您可以做的是@NamedEntityGraph定義物體的熱切獲取。在這里,您指定需要急切獲取的屬性(start和end)。要閱讀有關此內容的更多資訊,您可以在此處和此處查看。
@Entity
@Table(name = "edge")
@NamedEntityGraph(name = "Edge.nodes", attributeNodes = {
@NamedAttributeNode("start"),
@NamedAttributeNode("end")
}) // This is the important annotation
public class Edge {
@EmbeddedId
private EdgeKey id = new EdgeKey();
private int value;
@ManyToOne
@MapsId("startId")
@JoinColumn(name = "start_id", referencedColumnName = "id")
private Node start;
@ManyToOne
@MapsId("endId")
@JoinColumn(name = "end_id", referencedColumnName = "id")
private Node end;
// getters, setters...
}
@Embeddable
public class EdgeKey implements Serializable {
@Column(name = "start_id", nullable = false)
Integer startId;
@Column(name = "end_id", nullable = false)
Integer endId;
// getters, setters, equals and hash code...
}
此外,您可以使用以下內容注釋您的 JPA 存盤庫方法@EntityGraph:
@Repository
public interface EdgeRepository extends JpaRepository<Edge, Integer> {
@Override
@EntityGraph(value = "Edge.nodes", type = EntityGraph.EntityGraphType.LOAD)
List<Edge> findAll(); // You override the default implementation of findAll()
@EntityGraph(value = "Edge.nodes", type = EntityGraph.EntityGraphType.LOAD)
Edge getByValue(int value); // other example
}
這將導致類似于此的查詢:
SELECT edge0_.end_id AS end_id1_0_0_,
edge0_.start_id AS start_id2_0_0_,
node1_.id AS id1_1_1_,
node2_.id AS id1_1_2_,
edge0_.value AS value3_0_0_,
node1_.value AS value2_1_1_,
node2_.value AS value2_1_2_
FROM edge edge0_
LEFT OUTER JOIN node node1_ ON edge0_.start_id=node1_.id
LEFT OUTER JOIN node node2_ ON edge0_.end_id=node2_.id
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/311294.html
