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

使用两张表创建TypedQuery时遭遇SemanticException问题排查

问题原因分析

你的报错核心是混淆了JPQL与原生SQL的语法规则:EntityManager.createQuery()默认执行的是JPQL(面向实体的查询语言),但你写的是基于数据库表/列名的原生SQL语法,导致Hibernate无法解析语义。

具体错误点:

  • JPQL需使用实体类名而非数据库表名:你用了dining_table、reserved_slot,但对应的实体类是DiningTable、ReservedSlot
  • JPQL需使用实体属性名而非数据库列名:你用了dt.location(数据库列是LOCATION),但实体属性是tableLocation;子查询中的dining_table_id是数据库外键列,JPQL中应通过关联属性diningTable.id访问
解决方案

方案1:修正为JPQL查询(推荐)

按照实体类的属性和关联关系改写查询:

String findEmptyTableQuery = "SELECT dt FROM DiningTable dt " +
        "WHERE dt.tableLocation = ?1 " +
        "AND dt.id NOT IN (SELECT rs.diningTable.id FROM ReservedSlot rs)";
TypedQuery<DiningTable> findEmptyTable = entityManager.createQuery(findEmptyTableQuery, DiningTable.class);

说明:

  • 使用实体类名DiningTable、ReservedSlot代替数据库表名
  • 使用实体属性tableLocation代替数据库列名LOCATION
  • 子查询通过关联属性rs.diningTable.id获取关联的餐桌ID,而非直接用数据库外键列名

方案2:使用原生SQL查询

如果想保留原有的原生SQL语法,需使用createNativeQuery()方法:

String findEmptyTableQuery = "select * from dining_table dt " +
        "where dt.LOCATION = ?1 " +
        "and dt.ID not in ( select dining_table_id from reserved_slot )";
TypedQuery<DiningTable> findEmptyTable = entityManager.createNativeQuery(findEmptyTableQuery, DiningTable.class);

注意:原生SQL中要使用准确的数据库列名(需和实体@Column注解配置一致)。

额外验证点

检查实体类是否显式指定表名:如果你的实体类没有添加@Table(name = "dining_table")、@Table(name = "reserved_slot"),Hibernate会根据命名策略生成表名,可能和你预期的不一致,建议显式配置@Table注解避免歧义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:22:43