![](/img/trans.png)
[英]How to setup JPA bi-directional one to one while avoiding n+1 queries
[英]One to one mapping is triggering N+1 queries
我正在嘗試按照https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/進行 @OneToOne 映射,映射本身有效,但它觸發 N+1 查詢問題。
正在對父實體服務及其觸發 N+1 查詢進行查詢。 如何改進此代碼以僅進行 1 次查詢? 在這種情況下,我們不需要訪問 ParentDetails。
編輯:我試過使用 JPQL 和LEFT JOIN FETCH ParentDetails
也沒有工作。
EDIT2:只是為了嘗試添加更多信息。 我在 getParentDetails 上放了一個斷點,只是為了確保我沒有在任何地方調用 getter,也沒有打電話和仔細檢查,這似乎是 repo 調用的連接問題。
讓我們 go 到代碼:
家長
@Entity
@DynamicUpdate
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "parent")
private ParentDetails parentDetails;
// Getters, setters, etc omitted for brevity
}
家長詳情
@Entity
public class ParentDetails {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private Parent parent;
// Getters, setters, etc omitted for brevity
父詳細信息存儲庫
@Repository
public interface ParentRepository extends JpaRepository<Parent, Long> {
Page<Parent>findByNameOrderByName(@Param("name") final String name,final Pageable pageable);
}
Hibernate 執行附加查詢,因為父實體不 map 外鍵列。 Hibernate 不支持對關聯端的延遲獲取。 當 Hibernate 實例化一個 Parent object 時,它需要檢查是否需要初始化與代理或 null ZA8CFDE63311AC49EB26 的關聯。 在某個時候,團隊決定如果無論如何都被迫執行查詢,他們將獲取關聯的實體。 我在這里更詳細地解釋了這一點: https://thorben-janssen.com/hibernate-tip-lazy-loading-one-to-one
如果要避免額外的查詢,則需要 model ParentDetails 和 Parent 之間的單向關聯。 在您的示例中,這意味着您需要從 Parent 實體中刪除 parentDetails 屬性。
@Entity
@DynamicUpdate
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
// Getters, setters, etc omitted for brevity
}
因為您的 ParentDetails 實體使用與 Parent 實體相同的 id 值,所以您不需要雙向關聯。 如果要獲取 Parent 實體的 ParentDetails 實體,可以通過調用 em.find(...) 方法來獲取它
Parent p = // fetch the parent object ...
ParentDetails pd = em.find(p.getId(), ParentDetails.class);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.