我实际上是尝试使用JPA @OneToOne注释将Child实体链接到其Parent. 它运行良好,除了在获取Childs列表时,JPA引擎(在本例中为Hibernate)进行1 n次查询. 这是Hibernate查询的日志: select child0_.id as id1
它运行良好,除了在获取Childs列表时,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=?
使用完全相同的实体定义,当我特别得到一个孩子时,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
在获取带有Parent的Child实体列表时,有没有办法避免1 n个查询?
我终于找到了一个比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的帮助