Spring Data JPA:具有Specification和Pageable的findAll在计数查询上失败

时间:2018-07-09 23:05:25

标签: java count spring-data-jpa fetch specifications

我正试图在JpaSpecificationExecutor的findAll(Specification<T> spec, Pageable pageable)上获取一些数据。

我的规格是:

public static Specification<Report> isTemplate(boolean isTemplate) {
    return (root, query, cb) ->{
            root.fetch("entity1");
            root.fetch("entity2");
            root.fetch("entity3");
            root.fetch("entity4");
            root.fetch("entity5");
            return cb.equal(root.get("isTemplate"), isTemplate);
        }; 
}

报告中有5个子表(实体1 ...),这些子表与报告具有一对一的关系。

以下是他与某人的亲密关系的一个例子:

@OneToOne(fetch = FetchType.LAZY, mappedBy = "report")
@Fetch(FetchMode.JOIN)
public Entity1 getEntity1() {
    return this.entity1;
}

现在,当我使用规格调用List<T> findAll(Specification<T> spec)时,一切正常。但是当我调用Page<T> findAll(Specification<T> spec, Pageable pageable)失败时,到达计数查询并给出下一个异常:

  

“例外”:   “ org.springframework.dao.InvalidDataAccessApiUsageException”,   “ message”:“ org.hibernate.QueryException:查询指定的联接   正在抓取,但抓取的关联的所有者不在   选择列表... [从中选择count(generatedAlias0)   com.xxx.yyy.editor.entity.Report如generateAlias0内部联接获取   generateAlias0.report1作为generateAlias1内部联接获取   generateAlias0.report2 as generateAlias2 ...“

任何人都面临这个问题,或者知道为什么会发生这种情况。

我正在使用Spring Boot 1.5.9。

谢谢。

PD。我正在使用fetch在一个查询中获取所有关系。

1 个答案:

答案 0 :(得分:0)

我面临与您相同的问题。这里的问题是在分页时,它将调用一个计数查询,但是该计数查询不允许提取。

为克服此问题,我们必须通过检查查询的结果类型来防止在计数时进行访存,并且仅在结果类型不长时(当结果类型为长时,意味着执行了计数查询)才进行访存,如下所示:< / p>

public static Specification<Report> isTemplate(boolean isTemplate) {
    return (root, query, cb) -> {
        if (query.getResultType() != Long.class && query.getResultType() != long.class) {
            root.fetch("entity1");
            root.fetch("entity2");
            root.fetch("entity3");
            root.fetch("entity4");
            root.fetch("entity5");
        }
        return cb.equal(root.get("isTemplate"), isTemplate);
    }; 

}

您可以参考以下文章:

希望有帮助