首页 > 解决方案 > Spring Pageable 不翻译 @Column 名称

问题描述

我有实体对象:

@Entity(name = "table")
public class SomeEntity {

    @Id
    @Column(name = "id_column_name")
    public final BigDecimal entityId;

    @Column(name = "table_column_name")
    public final String entityFieldName;

}

我有这样定义的数据库视图:

CREATE OR REPLACE FORCE EDITIONABLE VIEW "V_TABLE" ("ID_COLUMN_NAME", "TABLE_COLUMN_NAME", "SOME_OTHER_COLUMN") AS ... (some SQL magic) 

我有自定义查询的存储库:

@RepositoryRestResource
interface SomeEntityRepository extends PagingAndSortingRepository<SomeEntity, BigDecimal> {

    @Query(value = "select id_column_name, table_column_name FROM V_TABLE where some_other_column = ?#{#parameter} order by ?#{#pageable}",
        countQuery = "SELECT count(*) from V_TABLE v where  some_other_column = ?#{#parameter}",
        nativeQuery = true)
    Page<SomeEntity> findBySomeParameter(@Param("parameter") long parameter, Pageable pageable);
} 

当我使用 url 请求标准数据时,一切正常: http://localhost:8080/someEntity/search/findBySomeParameter?parameter=25&page=0&size=20

但是当我添加排序信息时它不起作用: http://localhost:8080/someEntity/search/findBySomeParameter?parameter=25&page=0&size=20&sort=entityFieldName,asc 会抛出以下异常(我使用的是 Oracle 数据库):

Caused by: java.sql.SQLSyntaxErrorException: ORA-00904: "ENTITYFIELDNAME": invalid identifier

似乎排序字段没有用 翻译@Column(name),而是内联到 SQL 查询中。

有什么方法可以翻译可分页排序,以便它使用的不是字段名而是列名?

标签: javaspring-bootspring-data-jpaspring-rest

解决方案


这篇文章阐明了这个问题。从第 3.1 节开始阅读。

本机查询显然不支持动态排序。实际上,如果您将 findBySomeParameter 方法更改为采用 aSort而不是 aPageable您将得到org.springframework.data.jpa.repository.query.InvalidJpaQueryMethodException: Cannot use native queries with dynamic sorting.

使用 pageable 不会出现异常,并且分页实际上似乎工作正常,但动态排序不会替换您找到的列名。在我看来,唯一的解决方案是使用 JPQL 而不是本机查询,只要您需要进行的查询是您提供的查询,这不是问题。您需要将视图映射到 SomeEntityView 类才能使用 JPQL。

编辑 我认为这个问题没有记录,但它实际上在官方文档中

Spring Data JPA 目前不支持本地查询的动态排序,因为它必须操作声明的实际查询,而对于本地 SQL,它不能可靠地做到这一点。但是,您可以通过自己指定计数查询来使用本机查询进行分页,如以下示例所示:


推荐阅读