You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate4迁移至Hibernate5时Criteria查询报ORA-00904错误求助

Hibernate 4 迁移到 5 引发 Criteria 投影查询 ORA-00904 错误的原因分析

问题代码

public Integer getCount(QueryBuilder query) {
    Criteria criteria = getDao().buildCriteria(Summary.class, query);
    criteria.setProjection(count("id"));
    return ((Long) criteria.list().get(0)).intValue();
}

报错日志

ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - "ORA-00904: "THIS_"."CREATED_BY_USER_ID": invalid identifier"
ERROR controllers.UncaughtExceptionHandler - "Uncaught exception [org.hibernate.exception.SQLGrammarException] in handler [org.springframework.web.method.HandlerMethod] message [could not extract ResultSet > ORA-00904: "THIS_"."CREATED_BY_USER_ID": invalid identifier]"
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)

Caused by: java.sql.SQLSyntaxErrorException: ORA-00904: "THIS_"."CREATED_BY_USER_ID": invalid identifier

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)

Hibernate 4 到 5 的关键变化(对应此场景)

1. Criteria 投影与查询条件的关联处理逻辑变更

Hibernate 4中,设置投影(如count("id"))后,会自动忽略查询条件中未关联投影的字段/关联属性,不会将其加入生成的SQL。但Hibernate 5调整了这一行为:如果QueryBuilder中包含关联属性(比如CREATED_BY_USER_ID,可能是Summary关联的User实体属性)的查询条件,即使设置了投影,Hibernate 5仍会尝试在SQL中引入这些关联字段,若实体映射未正确配置该关联(或字段名不匹配),就会触发字段不存在的错误。

2. 关联查询的默认行为调整

  • Hibernate 4中,仅查询主实体投影字段时,即使有关联条件,也可能不会主动JOIN关联表;而Hibernate 5会强制生成JOIN语句,若关联属性映射存在歧义(比如字段大小写错误、注解配置错误),就会抛出ORA-00904。
  • 若QueryBuilder中使用了createAlias或fetch操作关联其他实体,Hibernate 5的SQL生成逻辑更严格,任何映射错误都会直接暴露为语法异常。

3. 投影查询的校验规则升级

Hibernate 5对投影与查询条件的组合做了更严格的校验:Hibernate 4会自动优化SQL,仅保留投影字段和必要的条件字段;Hibernate 5则严格按照查询条件中的属性生成SQL,若条件中的属性对应数据库字段不存在(或别名错误),直接触发语法错误。

4. 表别名生成规则变更

Hibernate 5调整了Criteria查询的表别名生成逻辑,主表默认别名变为THIS_。如果实体映射或QueryBuilder中硬编码了旧版本的别名,会导致字段引用错误(不过此场景中THIS_是合法主表别名,问题核心还是关联属性处理)。

解决思路参考

  • 检查Summary实体映射:确认CREATED_BY_USER_ID是表直接字段还是关联实体属性,若是关联属性,需确保QueryBuilder使用正确的关联路径(如user.id而非直接CREATED_BY_USER_ID)。
  • 清理投影无关的查询条件:设置count("id")投影后,移除QueryBuilder中与计数无关的关联条件或属性引用,避免Hibernate生成不必要的JOIN。
  • 显式指定关联策略:若必须保留关联条件,使用createAlias并指定关联类型(如LEFT_JOIN),确保生成正确的SQL JOIN语句。

内容的提问来源于stack exchange,提问作者Michu93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:27:22