在 Spring Data JPA 存储库中的公式中按带下划线的字段排序?

问题描述 投票:0回答:1

我正在使用 Spring Data JPA 存储库,并有一个本机查询,其中使用

CASE
语句创建其中一个字段,并给出带下划线的别名(例如
_myfield
)。此别名在查询的
ORDER BY
子句中使用。这就是我的课程的结构。

public class OuterClass() {
    
    /...
    @Id
    @Column(name = "id")
    private Integer id;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fk_inner", nullable = false, insertable = false, updatable = false)
    private InnerClass innerElement;

}

public class InnerClass() {
    
    /...

    @Formula("""
        CASE
            WHEN t2.field2 IS NULL THEN t2.field3
            ELSE t2.field2 || ' ' || t2.field4
        END) _my_field
    """
    private String _myField;

}

我在 JPA 存储库中尝试了不同的查询方法来获取

OuterClass
,但在尝试生成
ORDER BY
查询时,它们都返回相同类型的错误。我的一些尝试包括但不限于这些方法:

@EntityGraph(attributePaths = {"innerElement"})
@Query("SELECT o FROM OuterClass o WHERE o.id = :id ORDER BY o.innerElement._myField")
List<OuterElement> findById(@Param("id") Integer id);

@EntityGraph(attributePaths = {"innerElement"})
List<OuterElement> findByIdOrderByInnerElement__MyField(@Param("id") Integer id); 

这些都会生成相同的错误,因为 JPA 尝试通过包含

ORDER BY
语句来生成
CASE
子句

SELECT
  ...
WHERE 
  ...
ORDER BY 
  CASE
        WHEN t2.field2 IS NULL THEN t2.field3
        ELSE t2.field2 || ' ' || t2.field4
  END) _my_field

这总是会生成 SQL 异常。

Caused by: org.hibernate.exception.SQLGrammarException: JDBC exception executing SQL [select 
...,  (CASE
        WHEN t2.field2 IS NULL THEN t2.field3
        ELSE t2.field2 || ' ' || t2.field4
  END) _my_field
,
...
order by   (CASE
        WHEN t2.field2 IS NULL THEN t2.field3
        ELSE t2.field2 || ' ' || t2.field4
  END) _my_field
] [ERROR: syntax error at or near "_my_field"
  Position: 919] [n/a]
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:91) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:58) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:94) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:264) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.getResultSet(DeferredResultSetAccess.java:167) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.advanceNext(JdbcValuesResultSetImpl.java:265) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.processNext(JdbcValuesResultSetImpl.java:145) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.jdbc.internal.AbstractJdbcValues.next(AbstractJdbcValues.java:19) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.next(RowProcessingStateStandardImpl.java:67) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:204) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:33) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:211) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:83) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:76) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:65) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$2(ConcreteSqmSelectQueryPlan.java:139) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:382) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:302) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:526) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:423) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.hibernate.query.Query.getResultList(Query.java:120) ~[hibernate-core-6.5.3.Final.jar:6.5.3.Final]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:129) 

如何使此查询正常工作,同时在

ORDER BY
子句中将别名保留为 _myField?

java sql spring hibernate
1个回答
0
投票

请勿将

_my_field
包含在

    @Formula("""
        CASE
            WHEN t2.field2 IS NULL THEN t2.field3
            ELSE t2.field2 || ' ' || t2.field4
        END) _my_field
    """)
© www.soinside.com 2019 - 2024. All rights reserved.