如何在超类为MappedSuperclass的CriteriaQuery中引用子类字段
问题原因
- JPA的Criteria API调用
Root.get(String属性名)方法时,部分JPA实现(如低版本Hibernate)会优先从标注了@MappedSuperclass的父类元数据中查找对应属性,查找失败后不会自动检索子类的属性定义,因此抛出找不到属性的异常。 @MappedSuperclass标注的类本身不属于JPA实体,没有独立的表映射,因此不能作为查询根,也不能作为treat方法的处理目标,你之前尝试的相关方案自然会报错。
可行解决方案
方案1:使用JPA静态元模型(最推荐)
静态元模型可以完全规避字符串属性名拼写错误、类型不匹配、父类子类属性查找的问题,是JPA Criteria查询的标准最佳实践。
- 首先为实体类生成静态元模型:可以使用对应JPA实现的静态元模型生成工具,生成后会得到
ListCodes_元模型类。 - 修改查询代码如下:
CriteriaQuery<ListCodes> criteriaQuery = builder.createQuery(ListCodes.class); Root<ListCodes> listCodesRoot = criteriaQuery.from(ListCodes.class); // 直接使用静态元模型的属性引用 Predicate predicate = builder.equal(listCodesRoot.get(ListCodes_.codeTypeCode), "STATUSIND"); criteriaQuery.where(predicate);
方案2:显式指定属性类型
如果不想引入静态元模型,可以在调用get方法时显式指定属性的类型,强制JPA从子类的属性定义中查找匹配项:
Predicate predicate = builder.equal(listCodesRoot.get("codeTypeCode", String.class), "STATUSIND");
内容的提问来源于stack exchange,提问作者Peter DeNicola
相关产品推荐
相关产品推荐

