Ric*_*rdo 0 java mysql spring hibernate jpa
我正在尝试按照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,并且我没有调用并仔细检查,这似乎是存储库调用上的连接问题。
我们来看代码:
家长
@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
}
Run Code Online (Sandbox Code Playgroud)
家长详情
@Entity
public class ParentDetails {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private Parent parent;
// Getters, setters, etc omitted for brevity
Run Code Online (Sandbox Code Playgroud)
父详细信息存储库
@Repository
public interface ParentRepository extends JpaRepository<Parent, Long> {
Page<Parent>findByNameOrderByName(@Param("name") final String name,final Pageable pageable);
}
Run Code Online (Sandbox Code Playgroud)
Hibernate 执行额外的查询,因为父实体不映射外键列。Hibernate 不支持关联一端的延迟获取。当Hibernate实例化Parent对象时,它需要检查是否需要初始化与代理或空对象的关联。在某些时候,团队决定,如果他们无论如何都被迫执行查询,他们将获取关联的实体。我在这里更详细地解释了这一点:https://thorben-janssen.com/hibernate-tip-lazy-loading-one-to-one
如果您想避免额外的查询,则需要在 ParentDetails 和 Parent 之间建立单向关联模型。在您的示例中,这意味着您需要从 Parent 实体中删除 ParentDetails 属性。
@Entity
@DynamicUpdate
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
// Getters, setters, etc omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
由于您的 ParentDetails 实体使用与 Parent 实体相同的 id 值,因此您不需要双向关联。如果您想获取 Parent 实体的 ParentDetails 实体,可以通过调用 em.find(...) 方法来获取它
Parent p = // fetch the parent object ...
ParentDetails pd = em.find(p.getId(), ParentDetails.class);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2033 次 |
| 最近记录: |