在 Spring Boot 中向本机查询添加参数会导致“org.hibernate.exception.SQLGrammarException”,

Posted

技术标签:

【中文标题】在 Spring Boot 中向本机查询添加参数会导致“org.hibernate.exception.SQLGrammarException”,【英文标题】:Adding a parameter to a native query in Spring Boot causes "org.hibernate.exception.SQLGrammarException", 【发布时间】:2022-01-23 07:04:14 【问题描述】:

我在一个Spring Boot项目中创建了一个原生查询,在没有参数的情况下可以正常工作,如下:

@Query(nativeQuery = true, value="SELECT system_name as systemName, norcaType as norcaType, "
        + "device_number as deviceNumber,  feature_vector as featureVector, code as norcaCode, count(*) as sum "
        + "FROM (SELECT a.id, a.object_id, a.system_name, b.norca_type AS norcaType, device_number, "
        + "b.feature_vector, a.seqnb, a.object_index, c.code "
        + "FROM system_objectdata a " 
        + "JOIN sick_il_dacq.system_barcode_norca  b "
        + "ON a.id = b.system_objectdata_id " 
        + "AND a.partition_key  = b.partition_key " 
        + "JOIN system_feature_vector c " 
        + "ON b.feature_vector  = c.id " 
        + "JOIN sick_il_services.system_device d " 
        + "ON b.device_number = d.id) detail "  
        + "GROUP BY system_name, device_number, feature_vector")

public List<INorcaSummarySystemDeviceDTO> getNorcaSummaryBySystemAndDeviceAllSystems();

但是,当我添加一个带有单个参数的 where 子句时,它会给出一个 mysql 语法异常。

这是带有 WHERE 子句和参数的新查询:

@Query(nativeQuery = true, value="SELECT system_name as systemName, norcaType as norcaType, "
        + "device_number as deviceNumber,  feature_vector as featureVector, code as norcaCode, count(*) as sum "
        + "FROM (SELECT a.id, a.object_id, a.system_name, b.norca_type AS norcaType, device_number, "
        + "b.feature_vector, a.seqnb, a.object_index, c.code "
        + "FROM system_objectdata a " 
        + "JOIN sick_il_dacq.system_barcode_norca  b "
        + "ON a.id = b.system_objectdata_id " 
        + "AND a.partition_key  = b.partition_key " 
        + "JOIN system_feature_vector c " 
        + "ON b.feature_vector  = c.id " 
        + "JOIN sick_il_services.system_device d " 
        + "ON b.device_number = d.id"
        + "and a.system_name = ?1 ) detail "  
        + "GROUP BY system_name, device_number, feature_vector")

public List<INorcaSummarySystemDeviceDTO> getNorcaSummaryBySystemAndDeviceOneSystem(String systemName);

我知道原始 SQL 可以与 where 子句一起使用,因为我可以在 MySql Workbench 中运行它。

我也知道该参数正确通过,因为我在调试器中看到它并且它也显示在日志中。

我尝试了命名变量和索引变量,每次都得到相同的结果。

知道问题出在哪里吗?

这是日志中打印的错误:

2021/12/21 17:25:47.799 | ERROR | http-nio-8181-exec-6 | o.a.c.c.C.[.[.[.[dispatcherServlet]] | Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a.system_name = '02') detail GROUP BY system_name, device_number, feature_vector' at line 1
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:536)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:513)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:115)
    at com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1983)
    at com.mysql.cj.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1826)

【问题讨论】:

好像你在“ON b.device_number = d.id”这一行的d.id后面漏掉了一个空格,把它改成“ON b.device_number = d.id”然后测试 啊,一定是这样!我稍后会测试它,如果你做出答案,我会批准。 将其发布为答案 :) 【参考方案1】:

您在“ON b.device_number = d.id”这一行中的 d.id 之后似乎遗漏了一个空格,将其更改为“ON b.device_number = d.id”并测试

【讨论】:

以上是关于在 Spring Boot 中向本机查询添加参数会导致“org.hibernate.exception.SQLGrammarException”,的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 应用程序中向 STOMP CREATED 消息添加自定义标头?

无法在本机查询 Spring Boot 中使用“LIKE”

如何在 Spring Boot 的本机查询中使用 all(array[])?

Spring Boot JPA - 本机查询双撇号上的 SQL 错误

如何通过 Spring Boot JPA 执行具有 INTERVAL 子句的本机 SQL 查询?

使用带有 LIKE 的 mysql 本机查询的 spring boot 搜索返回空