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

HQL查询报错unexpected token: *该如何修复?

错误原因

报错unexpected token: *核心原因有两点:

  1. 你调用的是em.createQuery()方法,该方法会将传入语句按HQL(Hibernate面向实体的查询语言)规则解析,HQL原生不支持SELECT *的通配符写法,所有查询字段必须明确指定。
  2. 你编写的语句本质是Oracle风格原生SQL,包含大量HQL不识别的语法:比如数据库专属的ROWNUM关键字、直接关联物理表的JOIN写法、两层嵌套子查询结构,均不符合HQL解析规范。
修复方案

优先采用原生SQL方案,改动成本最低,无需调整现有实体映射:

  • 第一步:将em.createQuery()替换为em.createNativeQuery(),该方法会将语句直接传给数据库做原生SQL解析,不会走HQL语法校验。
  • 第二步:修正SQL里的两处隐性问题:
    • 把内层子查询的SELECT *改成SELECT id,内层派生表仅返回id单个字段,无需用通配符查询,同时可避免不同数据库下*带来的字段匹配问题
    • 给内层嵌套的派生表加别名,Oracle要求所有FROM后的子查询必须显式声明别名,否则会触发SQL语法错误

修正后可直接运行的SQL如下:

SELECT DISTINCT
    h.cod_1    AS cod1,
    h.cod_2    AS cod2,
    h.cod_3    AS cod3,
    w.stato    AS stato
FROM
    workflow w
    JOIN hist_1 h ON h.id = w.id_riga
    AND h.dt_perio_rif = '202111'
WHERE
        w.id_report = '1'
    AND w.id = (
        SELECT
            id
        FROM
            (
                SELECT
                    w2.id
                FROM
                    workflow w2
                WHERE
                        w2.id_riga = w.id_riga
                    AND w2.id_report = '1'
                ORDER BY
                    w2.update_date DESC
            ) t
        WHERE
            ROWNUM = 1
    );

对应的Java代码写法参考:

// 第二个参数可传入自定义结果DTO、实体类实现结果自动映射,不传则返回List<Object[]>类型结果
Query query = em.createNativeQuery(上述SQL语句, YourResultDTO.class);

如果必须用HQL实现,需做以下改造,整体改动成本较高:

  • 确认Workflow和Hist1两个实体的关联映射配置,HQL的JOIN基于实体关联属性实现,不能直接写物理表名+ON关联条件
  • 移除所有SELECT *写法,所有查询字段显式声明
  • 移除SQL里的ROWNUM关键字,HQL不支持数据库专属分页关键字,取第一条数据需要在创建Query后调用query.setMaxResults(1)实现
  • 调整嵌套子查询结构,HQL对子查询位置有严格限制,仅能出现在SELECT、WHERE子句中,部分版本不支持多层嵌套子查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:33:08