spring-data-jpa 如何在SpringDataJPA中使用带分页的投影接口?

bjp0bcyl  于 2022-11-10  发布在  Spring
关注(0)|答案(7)|浏览(196)

我正在尝试使用Spring Data 的新功能“投影”来获取部分实体(NetworkSimple)的页面
我已经检查了文档,如果我仅要求:

Collection<NetworkSimple> findAllProjectedBy();

它可以工作,但是如果我使用pagable:

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();
}
xa9qqrwz

xa9qqrwz1#

**注:**此功能应该按照原始发布者描述的方式工作,但由于this bug,它没有。该错误已在Hopper SR2版本中修复,如果您在较早版本中受阻,则以下解决方案将有效。

可以将Pageable与SpringDataJPA1.10中引入的新查询投影特性一起使用您将需要使用@Query注解并手动为所需的字段编写查询,还必须使用AS对它们进行别名处理,以使SpringData能够确定如何投影结果。在spring Boot 仓库的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将自动为分页信息派生一个计数查询。也可以在查询中使用连接来获取关联,然后在投影中对它们进行汇总。

hmae6n7t

hmae6n7t2#

我认为你需要创建findAllProjectedBy()作为规范。然后你可以像这样使用findAll()方法。
例如:findAll(findAllProjectedBy(),pageable)
以下链接可能有助于找到如何在Spring中创建规范。
https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

gcuhipw9

gcuhipw93#

问题可能来自于方法名称。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);

5vf7fwbs

5vf7fwbs4#

即使使用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重命名为findAllBy,例如

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

rjee0c155#

您可以将界面投影与Pageable一起使用,如下所示:

Page<NetworkSimple> findPagedProjectedBy(Pageable pageable);

具有一些参数:

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

3df52oht6#

使用分页实现接口投影

1.我们的ResourceEntity.java

@Getter
@Setter
@NoArgsConstructor
@Entity
public class ResourceEntity{
    private Long id;
    private String name;
}

2.创建投影接口名称ProjectedResource.java,该接口Map通过存储库层方法中的SQL查询收集的数据

public interface ProjectedResource {
  Long getId();
  String getName();
  String getAnotherProperty();
}

3.创建Repository层的方法:getProjectedResources()

  • 我们考虑的数据库表名是resource
  • 我们在这里只读取idname
@Query(name="select id, name, anotherProperty from resource", countQuery="select count(*) from resource", nativeQuery=true)
Page<ProjectedResource> getProjectedResources(Pageable page);

希望问题能得到解决!

js81xvg6

js81xvg67#

您可以用途:

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

相关问题