Spring Boot - Jpa Distinct 和 Pageable

Posted

技术标签:

【中文标题】Spring Boot - Jpa Distinct 和 Pageable【英文标题】:Spring Boot - Jpa Distinct and Pageable 【发布时间】:2020-01-19 14:54:56 【问题描述】:

我有一个使用 kotlin 的 Spring Boot v 2.1.8.RELEASE 项目。 我们使用 postgres 数据库,我有以下 JPA 查询

    @Query(value = " SELECT distinct grievance " +
               " FROM Grievance grievance" +
               " WHERE (grievance.auditProgramPortal=:auditProgramPortal AND grievance.owner.id=:organizationId) " +
               " OR (grievance.status=:status AND grievance.auditProgramPortal=:auditProgramPortal)" +
               " OR (grievance.auditProgramPortal=:auditProgramPortal AND grievance.owner.id=:organizationId)" +
               " OR (grievance.auditProgramPortal=:auditProgramPortal AND grievance.publicSubmission=:publicSubmission)")
fun findAnalystBodyGrievances(
        auditProgramPortal: Boolean,
        organizationId: Long,
        status: GrievanceStatus,
        publicSubmission: Boolean,
        pageable: Pageable): Page<Grievance>

当我按原样运行它时 - 它工作得很好。当我对行业领域进行排序时(参见下面的对象) - 我收到以下错误

org.postgresql.util.PSQLException: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list

相关对象的片段如下

申诉

@Entity
@Audited
@Table(name = "grievance")
class Grievance 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    var id: Long? = null

    @Column(name = "title", nullable = false)
    var title: String? = null

    @Column(name = "description", columnDefinition = "text")
    var description: String? = null

    @Column(name = "public_description", columnDefinition = "text")
    var publicDescription: String? = null

    @Column(name = "related_to_identified_risk")
    var relatedToIdentifiedRisk: Boolean? = null


    @OneToOne
    @JoinColumn(name = "industry_id")
    var industry: Industry? = null
  

行业

@Entity
@Table(name = "industry")
class Industry 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    var id: Long? = null

    @Column(name = "name", nullable = false, unique = true)
    var name: String? = null

    @Column(name = "color", nullable = false, unique = false)
    var color: String? = null

我的问题是 - 修复查询以便仍然返回页面的最简单方法是什么 如果我更新我的代码以使用以下查询 - 返回一个通用对象

@Query(value = " SELECT distinct grievance, grievance.industry " +
               " FROM Grievance grievance" +
               " WHERE (grievance.auditProgramPortal=:auditProgramPortal AND grievance.owner.id=:organizationId) " +
               " OR (grievance.status=:status AND grievance.auditProgramPortal=:auditProgramPortal)" +
               " OR (grievance.auditProgramPortal=:auditProgramPortal AND grievance.owner.id=:organizationId)" +
               " OR (grievance.auditProgramPortal=:auditProgramPortal AND grievance.publicSubmission=:publicSubmission)")

非常感谢任何帮助

【问题讨论】:

我使用了以下技巧 - 我将 @Formula (theExpressionThere) 作为实体中的一个字段引入并使用表达式排序。 谢谢@StanislavL - 你有什么有用的例子来说明如何使用它吗? 你在pageable 参数中传递了什么? @KamilW 是 org.springframework.data.domain.Pageable 对象的一个​​实例 如果您在原始 jpql 中删除 distinct,那么它会排序吗?你能分享一下你是如何构建可分页的吗?当行业是申诉的一部分时,它不应该抛出这个错误。 【参考方案1】:

下面试试

@Query(value =" Select grievance from (SELECT distinct grievance, grievance.industry " +
" FROM Grievance grievance" +
" WHERE (grievance.auditProgramPortal=:auditProgramPortal AND grievance.owner.id=:organizationId) " +
" OR (grievance.status=:status AND grievance.auditProgramPortal=:auditProgramPortal)" +
" OR (grievance.auditProgramPortal=:auditProgramPortal AND grievance.owner.id=:organizationId)" +
" OR (grievance.auditProgramPortal=:auditProgramPortal AND grievance.publicSubmission=:publicSubmission))")

【讨论】:

一个可能的解决方案,但我希望使用 1 个查询来摆脱困境。感谢您的回复 这是我想到的第一件事,但更快的方法,因为所有操作都将在数据库服务器上执行,如果我想到其他事情,我会添加 我试过了,但是JPA不支持FROM (SELECT ... @Purfakt 你能发布一个新的帖子来解释你的问题,你尝试了什么以及你想要实现什么

以上是关于Spring Boot - Jpa Distinct 和 Pageable的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot(十五):spring boot+jpa+thymeleaf增删改查示例

[Spring Boot] Adding JPA and Spring Data JPA

spring-data-jpa 和 spring-boot-starter-data-jpa 的区别

spring boot jpa

Spring Boot 整合Spring Data JPA

Spring Boot中使用Spring Data JPA示例