使用两张表创建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
相关产品推荐
相关产品推荐

