Hibernate SQL语法错误:无法提取ResultSet问题求助
问题排查:ORA-00923与Hibernate SQL语法错误
错误现象
执行代码时触发ORA-00923: FROM keyword not found where expected错误,伴随Hibernate的SQLGrammarException,无法提取ResultSet。
错误根源
- 原生SQL混用JPQL语法:Repository的
@Query开启了nativeQuery=true,却使用了JPQL专属的NEW 实体类构造器语法,Oracle原生SQL不支持这种写法,直接导致语法解析失败。 - 构造器参数不匹配:即使使用JPQL,查询中传入构造器的参数(
sn, clientid, ticket_count)与实体类现有构造器的参数数量、顺序完全不匹配,会引发实例化错误。 - 视图名称拼写不一致:实体类注解中视图名为
vw_dupicate_ticket_count_qbr_reltag(duplicate少写一个l),但日志中生成的SQL使用了正确拼写的vw_duplicate_ticket_count_qbr_reltag,名称不匹配会导致找不到表/视图。 - 数组参数处理不规范:原生SQL中直接用
IN(?)处理字符串数组,Hibernate对这种写法的解析可能存在问题,导致SQL语法异常。
解决方案
方案一:使用JPQL(推荐,符合JPA规范)
步骤1:添加匹配的实体构造器
在DuplicateManagerMetricsRelTagEntity中添加对应查询参数的构造器:
public DuplicateManagerMetricsRelTagEntity(Integer sn, String clientid, Integer ticket_count) { this.sn = sn; this.clientid = clientid; this.ticket_count = ticket_count; // 其他非必填字段可设为null或默认值 }
步骤2:修正Repository的查询语句
去掉nativeQuery=true,使用JPQL语法(基于实体类而非数据库表名):
@Query("select NEW qbr.entity.DuplicateManagerMetricsRelTagEntity(a.sn, a.clientid, a.ticket_count) " + "from DuplicateManagerMetricsRelTagEntity a " + "where a.clientid = ?1 AND a.appid in (?2) AND a.releasetag=?3") List<DuplicateManagerMetricsRelTagEntity> getAllDuplicateManagerfromReleaseTag(String clientid, String[] appid, String releasetag);
步骤3:统一视图名称拼写
修正实体类的@Table注解,使用正确的视图名称(duplicate):
@Table(name = "vw_duplicate_ticket_count_qbr_reltag")
方案二:使用原生SQL(适用于复杂SQL场景)
步骤1:修正SQL语句,移除JPQL构造器
直接查询实体类对应的所有字段,让Hibernate自动映射,同时规范数组参数的传递:
@Query(value = "select sn, releasetag, reporting_month, clientid, appid, ticket_count " + "from vw_duplicate_ticket_count_qbr_reltag a " + "where a.clientid = ?1 AND a.appid in (:appid) AND a.releasetag=?3", nativeQuery = true) List<DuplicateManagerMetricsRelTagEntity> getAllDuplicateManagerfromReleaseTag( String clientid, @Param("appid") String[] appid, String releasetag );
注意:查询字段的顺序需与实体类属性的声明顺序一致,或字段名与属性名完全匹配,确保Hibernate能正确映射。
步骤2:统一视图名称拼写
同方案一,修正实体类的@Table注解为正确的视图名称。
额外验证点
- 确认Controller中
@PathVariable String[] appid的URL传递方式是否正确:多个appid需用逗号分隔(如/qbr/duplicatemanager/657/657-001,657-002/WIL657.2021.05-001/),Spring会自动解析为字符串数组。 - 执行修改后,查看Hibernate生成的SQL日志,确认语法正确无拼写错误。
内容的提问来源于stack exchange,提问作者Prithu Singh Kathet
相关产品推荐
相关产品推荐

