我正在使用spring-data-jpa规范API,并希望查询和获取父实体及其关联,而不会引起N + 1问题。
所有实体的代码如下。有两个一对一关联。
为了实现不使用N + 1的联接查询,我尝试了两种方法:root.fetch("policy",JoinType.LEFT)
和@EntityGraph annotation
。
通过这两种方法,都将正确记录带有join子句的第一个主SQL。 但 使用root.fetch方法,我得到了下面描述的异常。
.hibernate.QueryException:查询指定了连接提取,但选择列表中不存在获取的关联的所有者[FromElement {explicit,不是集合连接,获取连接,获取非惰性属性,classAlias = generateAlias3, role = com.xxx.model.OrderTrack.policy,tableName = pro_lafs_policy,tableAlias = policy3_,origin = tordertrack ordertrack0_,columns = {ordertrack0_.billno,className = com.xxx.model.Policy}}
使用EntityGraph,N + 1仍然发生,我可以在日志中看到。
@Entity
@Table(name="tordertrack")
@JsonAutoDetect
public class OrderTrack {
private Long oid;
private String billno;
@OneToOne
@JoinColumn(name = "billno",referencedColumnName = "bill_no",updatable = false,insertable = false)
private Policy policy;
}
@Entity
public class Policy{
@Id
private long id;
@Column(name = "BILL_NO")
private String billNo;
}
//in Service method:
public Predicate toPredicate(Root<OrderTrack> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
root.fetch("policy",JoinType.LEFT);
root.fetch("returnVisit",JoinType.LEFT);
}
service.findAll(specification,pageable);
//with @EntityGraph
@Override
@EntityGraph(attributePaths = {"policy","returnVisit"})
Page<OrderTrack> findAll(Specification<OrderTrack> var1, Pageable var2);
感谢您的帮助。