HQL如何访问joined-subclass连接子类的关联属性?
Hibernate HQL查询问题修复方案
错误原因
- 核心问题:
patient属性属于AnsweredForm的子类PatientForm,并非父类AnsweredForm的自有属性,直接通过answer.answeredForm.patient访问时,Hibernate无法自动完成向下转型,导致生成SQL时表别名逻辑混乱,最终抛出找不到对应表项的错误。 - 原HQL存在冗余写法:显式声明了
JOIN answeredForm answeredForm但未使用该别名,反而在WHERE子句继续通过answer.answeredForm访问属性,额外生成了不必要的交叉连接。
正确HQL写法
写法1:使用TREAT函数(推荐,适配Hibernate 4.3及以上版本)
TREAT是HQL提供的向下转型专用函数,明确告知Hibernate将AnsweredForm实例作为PatientForm子类处理,生成正确的关联逻辑:
SELECT answer FROM DataCollection answer WHERE TREAT(answer.answeredForm AS PatientForm).patient.code = :patientCode
如果需要优化关联查询性能,也可以显式JOIN:
SELECT answer FROM DataCollection answer JOIN TREAT(answer.answeredForm AS PatientForm) patientForm WHERE patientForm.patient.code = :patientCode
写法2:等值连接适配低版本(适配Hibernate 4.3以下版本)
如果使用的Hibernate版本不支持TREAT函数,可以通过父类子类主键等值匹配的方式实现需求:
SELECT answer FROM DataCollection answer, PatientForm patientForm WHERE answer.answeredForm.id = patientForm.id AND patientForm.patient.code = :patientCode
内容的提问来源于stack exchange,提问作者mmalmeida
相关产品推荐
相关产品推荐

