performance - JPA @OneToOne 选择带有 N+1 个查询的列表

标签 performance hibernate jpa one-to-one select-n-plus-1

我实际上是在尝试使用 JPA @OneToOne链接 Child 的注释实体到其 Parent .

它运行良好,除了在获取 Child 列表时s,JPA 引擎(在本例中为 Hibernate)进行 1+n 次查询。

这是 Hibernate 查询的日志:

select child0_.id as id1_0_, child0_.parent as parent3_0_, child0_.value as value2_0_ from child child0_
select parent0_.id as id1_1_0_, parent0_.something as somethin2_1_0_ from parent parent0_ where parent0_.id=?
select parent0_.id as id1_1_0_, parent0_.something as somethin2_1_0_ from parent parent0_ where parent0_.id=?
select parent0_.id as id1_1_0_, parent0_.something as somethin2_1_0_ from parent parent0_ where parent0_.id=?

使用完全相同的实体定义,特别是当我得到一个 child 时,JPA 使用预期的 JOIN 执行查询:
select child0_.id as id1_0_0_, child0_.parent as parent3_0_0_, child0_.value as value2_0_0_, parent1_.id as id1_1_1_, parent1_.something as somethin2_1_1_ from child child0_ left outer join parent parent1_ on child0_.parent=parent1_.id where child0_.id=?

这是Child实体定义:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "child")
public class Child {

    @Id
    private Long   id;
    @Column
    private String value;
    @OneToOne(optional = false)
    @JoinColumn(name = "parent")
    private Parent parent;

}

Parent实体 :
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "parent")
public class Parent {

    @Id
    private Long   id;
    @Column
    private String something;

}

您可以在此处找到运行代码的完整示例:
https://github.com/Alexandre-Carbenay/demo-jpa-onetoone

获取 Child 的列表时,有没有办法避免 1+n 查询实体 Parent ?

最佳答案

我终于找到了比 JOIN FETCH 更好的解决方案也适用于 QueryDsl,使用 @EntityGraph关于存储库方法的注释。

这是更新的 Child定义 :

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@NamedEntityGraph(name = "Child.withParent", attributeNodes = @NamedAttributeNode("parent"))
@Table(name = "child")
public class Child {
    @Id
    private Long   id;
    @Column
    private String value;
    @OneToOne(optional = false)
    @JoinColumn(name = "parent")
    private Parent parent;
}

ChildJpaRepository定义 :
public interface ChildJpaRepository extends JpaRepository<Child, Long>, QueryDslPredicateExecutor<Child> {

    @Override
    @EntityGraph("Child.withParent")
    List<Child> findAll();

    @Override
    @EntityGraph("Child.withParent")
    List<Child> findAll(Predicate predicate);

}

感谢 Simon Martinelli 和 Vlad Mihalcea 的帮助

关于performance - JPA @OneToOne 选择带有 N+1 个查询的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47754497/

相关文章:

linux - 用于 Linux 的开源 OpenGL 分析器

java - 你什么时候会在 postgres 可序列化隔离级别上使用 Hibernate 乐观锁?

java - "org.hibernate.DuplicateMappingException"错误是什么意思?

c# - 并行 C# 线程性能问题

java - 数组中的随机数,其中均值是整数

mysql - mysql索引是否在更新时修改?

java - 请提供 hibernate 条件中 If 语句的示例

java - 使用 ehcache 时出错

java - Hibernate @OneToOne双向导致冗余select查询

hibernate - 在 Wildfly 8.1 的 war 文件中使用自定义 JPA/Hibernate 提供程序