![](/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.