【问题标题】:Hibernate/Spring Data JPA is not able to identify WITHIN keyword in Spring Boot applicationHibernate/Spring Data JPA 无法识别 Spring Boot 应用程序中的 WITHIN 关键字
【发布时间】:2019-01-29 12:32:08
【问题描述】:

我正在为我的 Entity/Pojo 类中的一个属性使用@Formula 注释。在运行时,它会创建一个查询来获取结果,并抛出 ERROR ORA-02000: missing WITHIN keyword,因为它无法将 WITHIN 识别为关键字。

Marks.java

@Formula("(SELECT CASE WHEN dis_order IS NULL THEN (SELECT listagg(qpm.displayed_order,', ') WITHIN GROUP (ORDER BY qpm.displayed_order) FROM que_post_mark qpm WHERE qpm.es_id = es_id AND qpm.sez_id = sez_id GROUP BY qpm.es_id, qpm.sez_id) ELSE NULL END FROM dual)")
private String childItemsDisplayedOrder;

生成的查询如下:

select marks0_.*,
(SELECT
    CASE 
        WHEN marks0_.displayed_order IS NULL THEN (SELECT
            listagg(qpm.displayed_order,
            ', ') marks0_.WITHIN 
        GROUP (ORDER BY
            qpm.displayed_order) 
        FROM
            que_post_mark qpm 
        WHERE
            qpm.es_id  = marks0_.es_id  
            AND qpm.sez_id = marks0_.sez_id 
        GROUP BY
            qpm.es_id ,
            qpm.sez_id) 
        ELSE NULL 
    END 
FROM
    dual) as formula2_0_ 
from
    MARKS marks0_ 
where
    marks0_.es_id =?

它将WITHIN 标识为列并附加别名,如marks0_.WITHIN

我正在使用以下版本:

 spring-boot-starter-web = 1.4.0.RELEASE, spring-data-jpa:jar:1.10.2 ,hibernate-entitymanager:jar:5.1.3' hibernate-core:jar:5.1.3, hibernate-jpa-2.1-api:jar

我尝试降低这些 jar 版本以使其正常工作,但没有成功。

错误堆栈跟踪如下:

Caused by: java.sql.SQLSyntaxErrorException: ORA-02000: missing WITHIN keyword

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:774)
    at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:925)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1111)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
    at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:4845)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1501)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56)
    ... 136 common frames omitted

谁能帮我解决这个问题?

【问题讨论】:

  • 如果您删除marks0_.WITHIN 上的别名,您可以在数据库前端运行生成的查询吗?
  • @AlanHay 如果我删除别名(marks0_.) 并在 SQL 开发人员中运行,查询将按预期工作。
  • 看到这个问题似乎无法识别关键字 WITHIN。您可以通过创建给定答案中概述的自定义方言轻松修复:stackoverflow.com/questions/23335509/…
  • 虽然我在 cmets 中看到有人专门为 WITHIN 尝试过,但没有成功。我的偏好是将这些复杂性排除在 Java 代码之外,并通过数据库视图在数据库中处理。然后,您可以使用@SecondaryTable 将视图中的数据映射到您的实体。 childItemsDisplayedOrder 字段就像其他任何字段一样。您需要将其设置为 Integer 类型而不是 int 但是以防止不需要的插入。

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


【解决方案1】:

我已经通过扩展 this link 中提到的休眠方言类解决了这个问题

public class Oracle10gDialectExtended extends Oracle10gDialect {
    public Oracle10gDialectExtended() {
        super();
        registerKeyword("within"); //Keyword has to be in lowercase.
    }
}

用这个新类设置“hibernate.dialect”属性。

Properties.setProperty("hibernate.dialect", "com.example.Oracle10gDialectExtended");

【讨论】:

  • 或者在 Spring Boot 中:spring.jpa.properties.hibernate.dialect=com.example.Oracle10gDialectExtended
猜你喜欢
  • 2019-01-22
  • 1970-01-01
  • 2017-11-29
  • 2022-01-09
  • 1970-01-01
  • 2020-12-09
  • 2018-09-17
  • 2022-01-04
  • 2015-04-04
相关资源
最近更新 更多