使用带有连接的JPA CriteriaQuery时,Spring Data REST抛出错误

时间:2015-02-10 05:09:28

标签: spring-data-jpa spring-data-rest

当使用带有JPA / Hibernate的Spring Data REST并通过REST公开spring JpaRepository时,我收到了JPA Criteria查询的错误。这是一个Spring Boot应用程序。

一些相关实体:

@Entity
public class Appointment {  
...  
...  
@ManyToOne(fetch=FetchType.EAGER)  
@JoinColumn(name="doctor_id", insertable=false, updatable=false)  
private Doctor doctor;  
...  
...  
}  

@Entity
public class Doctor {  
...  
...  
@Column(name = "doctor_name")  
private String doctorName = "";  
...  
...  
}  

尝试返回与医生姓名匹配的约会列表,我的JPA规范如下:

public Specification<Appointment> getSpecification() {
    return new Specification<Appointment>() {

        Join<Appointment, Doctor> doctorJoin;

        @Override
        public Predicate toPredicate(Root<Appointment> root, 
                CriteriaQuery<?> query, 
                CriteriaBuilder cb) {
            Predicate p = cb.conjunction();
            ... //other critieria
            p = addDoctorCriteria(p, cb, root, Doctor_.doctorName, getDoctorName());

            return p;
        }


        private Predicate addDoctorCriteria(Predicate p,
                CriteriaBuilder cb, Root<Appointment> root, SingularAttribute<Doctor, String> property, String value) {

            value = value + '%';

            if (doctorJoin == null) {
                doctorJoin = root.join(Appointment_.doctor);
            }

            p = cb.and(p, cb.like(cb.lower(doctorJoin.<String>get(property)), value));

            return p;
        }
    };
}

这会引发以下异常:

org.hibernate.hql.internal.ast.QuerySyntaxException:  
Invalid path: 'generatedAlias1.doctorName'  
[select count(generatedAlias0) from my.package.Appointment as generatedAlias0   
where ( 1=1 ) and ( lower(generatedAlias1.doctorName) like :param0 )];  

看起来连接查询不正确 - 没有“生成过来”和“#39;在from子句中。当Spring试图获取行数以构建分页信息时,似乎正在发生这种情况。取决于约会属性的其他标准(即没有连接)效果很好。

我正在正确加入JPA吗?有关如何纠正此错误的任何建议吗?

1 个答案:

答案 0 :(得分:0)

以下是我如何使用此功能,以防有人遇到此问题:

Root<Doctor> doctor = query.from(Doctor.class);
Predicate j1 = cb.equal(root.get(Appointment_.doctor), doctor);
Predicate c1 =  cb.like(cb.lower(doctor.<String>get(Doctor_.doctorName)), getDoctorName() + '%');
p = cb.and(p, cb.and(j1, c1));