如何在Spring Data JPA中使用具有分页功能的投影接口?

时间:2016-04-18 18:12:08

标签: spring hibernate jpa spring-data spring-data-jpa

我正在尝试使用spring数据的新功能projections

获取部分实体(NetworkSimple)的页面

我已经检查了文档,如果我只是请求:

Collection<NetworkSimple> findAllProjectedBy();

它有效,但如果我使用可分页:

Page<NetworkSimple> findAllProjectedBy(Pageable pageable);

它会抛出错误:

org.hibernate.jpa.criteria.expression.function.AggregationFunction$COUNT cannot be cast to org.hibernate.jpa.criteria.expression.CompoundSelectionImpl

任何人都已经使用过吗?

我的NetworkSimple类如下:

public interface NetworkSimple {
    Long getId();

    String getNetworkName();

    Boolean getIsActive();
}

6 个答案:

答案 0 :(得分:11)

注意:此功能应按照原始海报所描述的方式运行,但由于this bug没有。针对Hopper SR2版本修复了该错误,如果您遇到早期版本,则下面的解决方法将有效。

可以将Pageable与Spring Data JPA 1.10(Hopper)中引入的新查询投影功能结合使用。您需要使用@Query注释并手动编写所需字段的查询,还必须使用AS对其进行别名,以允许Spring Data找出如何投影结果。在Spring引导库的spring-boot-samples部分有一个很好的例子。

在你的例子中,这很简单:

@Query("SELECT n.id AS id, n.name AS networkName, n.active AS isActive FROM Network n")
Page<NetworkSimple> findAllProjectedBy(Pageable pageable);

我假设您的实体看起来像这样:

@Entity
public class Network
{
    @Id
    @GeneratedValue
    private Long id;

    @Column
    private String name;

    @Column
    private boolean active;

    ...
}

Spring Data将自动为寻呼信息导出计数查询。也可以在查询中使用连接来获取关联,然后在投影中对它们进行汇总。

答案 1 :(得分:0)

问题可能来自方法名称。 by关键字表示您通过特定属性过滤数据:例如findByName。它从方法名称中调用查询:

http://docs.spring.io/spring-data/jpa/docs/1.10.1.RELEASE/reference/html/#repositories.query-methods.query-creation

请尝试使用Page<NetworkSimple> findAll(Pageable pageable);

答案 2 :(得分:0)

我认为您需要创建findAllProjectedBy()作为规范。然后您可以像这样使用findAll()方法。

示例:findAll(findAllProjectedBy(),pageable)

以下链接可能有助于找到如何在春季创建规范。

https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

答案 3 :(得分:0)

您可以使用:

@Query("SELECT n FROM Network n")
Page<? extends NetworkSimple> findAllProjectedBy(Pageable pageable);

答案 4 :(得分:0)

即使使用spring-data-jpa 1.11.4,也可以像

public interface NetworkRepository extends JpaRepository<Network, String> {
    Page<NetworkSimple> findAll(Pageable pageable);
}

不会编译;报告

findAll(org.springframework.data.domain.Pageable) in NetworkRepository clashes with findAll(org.springframework.data.domain.Pageable) in org.springframework.data.repository.PagingAndSortingRepository
return type org.springframework.data.domain.Page<NetworkSimple> is not compatible with org.springframework.data.domain.Page<Network>

我们找到的解决方法是将findAll重命名为findAll ,例如

public interface NetworkRepository extends JpaRepository<Network, String> {
    Page<NetworkSimple> findAllBy(Pageable pageable);
}

答案 5 :(得分:0)

您可以像这样在Pageable中使用界面投影:

Page<NetworkSimple> findPagedProjectedBy(Pageable pageable);

带有一些参数:

Page<NetworkSimple> findPagedProjectedByName(String name, Pageable pageable);