java一对一映射正在触发N+1查询
我试图在https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/之后创建一个@OneToOne映射,映射本身可以工作,但它会触发一个N+1查询问题
正在对父实体服务及其触发的N+1查询进行查询。 如何改进此代码,使其只进行一次查询在这种情况下,我们不需要访问ParentDetails
编辑:我尝试过使用JPQL和LEFT JOIN FETCH ParentDetails
,但也没有成功
编辑2:只是想添加更多信息。我在getParentDetails上设置了一个断点,只是为了确保我没有在任何地方调用getter,也没有调用和重复检查,而且在repo调用上似乎存在连接问题
让我们转到代码:
家长
@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
ParentDetailsRepository
@Repository
public interface ParentRepository extends JpaRepository<Parent, Long> {
Page<Parent>findByNameOrderByName(@Param("name") final String name,final Pageable pageable);
}
# 1 楼答案
Hibernate执行附加查询,因为父实体不映射外键列。Hibernate不支持该关联端的延迟抓取。当Hibernate实例化父对象时,它需要检查是否需要初始化与代理或空对象的关联。在某个时刻,团队决定,如果强制执行查询,他们将获取关联的实体。我在这里更详细地解释了这一点:https://thorben-janssen.com/hibernate-tip-lazy-loading-one-to-one
如果希望避免额外的查询,则需要在ParentDetails和Parent之间建立单向关联模型。在您的示例中,这意味着您需要从父实体中删除parentDetails属性
由于ParentDetails实体使用与父实体相同的id值,因此不需要双向关联。如果要获取父实体的ParentDetails实体,可以调用em.find(…)方法