Spring Boot CriteriaQuery Attribute Not Found错误排查求助
问题分析与修复方案
核心问题梳理
- BaseEntity注解冲突:
BaseEntity同时标注了@MappedSuperclass和@Entity,这会导致JPA错误识别父类类型,进而在解析子类属性时出现查找路径混乱。@MappedSuperclass是用于继承映射的非实体类标记,不能与@Entity共存。 - CriteriaQuery泛型错误:代码中
CriteriaQuery<Book>是明显笔误,应改为CriteriaQuery<Student>。 - 变量名冲突:
Root<Student> student与方法参数Student student重名,导致局部变量覆盖参数,后续属性查找逻辑混乱。 - 嵌入式ID属性访问错误:Student的
id是嵌入式复合主键StudentID,不能直接通过student.get("id")获取底层字段,必须先定位到嵌入式对象,再访问其内部属性。 - 未定义变量引用:代码中使用了
authorNamePredicate、titlePredicate等未定义的变量,属于明显笔误。
修正后的代码
1. 修正BaseEntity注解
@MappedSuperclass class BaseEntity { @Column(name = "start_date") Date startDate; @Column(name = "end_date") Date endDate; }
2. 修正StudentDao查询方法
@Repository class StudentDao { private final EntityManager em; // 构造注入EntityManager public StudentDao(EntityManager em) { this.em = em; } List<Student> findStudentsByCriteria(Student student) { CriteriaBuilder cb = em.getCriteriaBuilder(); // 修正泛型类型 CriteriaQuery<Student> cq = cb.createQuery(Student.class); // 重命名Root变量,避免与参数冲突 Root<Student> rootStudent = cq.from(Student.class); // 正确访问嵌入式ID的属性:先获取嵌入式对象,再访问内部字段 Predicate studentIdPredicate = cb.equal(rootStudent.get("id").get("id"), student.getId().getId()); Predicate studentDeptPredicate = cb.equal(rootStudent.get("id").get("dept_id"), student.getId().getDept_id()); // 使用正确的Predicate变量 cq.where(studentIdPredicate, studentDeptPredicate); TypedQuery<Student> query = em.createQuery(cq); return query.getResultList(); } }
额外优化建议
- 使用类型安全的Metamodel API替代字符串属性名,避免拼写错误,例如:
rootStudent.get(Student_.id).get(StudentID_.id)(需提前生成Metamodel类)。 - 确保Lombok的
@Data注解正确生成了所有getter/setter,尤其是嵌入式ID类的方法。
内容的提问来源于stack exchange,提问作者Venkat
相关产品推荐
相关产品推荐

