Java 翻译SQL时出现问题';在';将子查询转换为JPA条件查询

Java 翻译SQL时出现问题';在';将子查询转换为JPA条件查询,java,sql,jpa,criteria-api,Java,Sql,Jpa,Criteria Api,我正在尝试将此SQL查询转换为JPA条件查询: select distinct student0_.name from vnic03.student student0_ where (exists(select teacher0_.social_number from vnic03.teacher teacher0_ where teacher0.social_number = ? and teacher0_.school_id

我正在尝试将此SQL查询转换为JPA条件查询:

select distinct student0_.name 
from vnic03.student student0_
where (exists(select teacher0_.social_number
          from vnic03.teacher teacher0_
          where teacher0.social_number = ?
            and teacher0_.school_id in (select school0_.id
                                               from vnic03.school school0_
                                               where school0_.student_id = student0_.id)))  
这些是表(我已经简化并重命名了它们,以便发布在这里,实际上它们有数百万条条目):

现在我有以下代码:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<String> searchQuery = criteriaBuilder.createQuery(String.class);
Root<Student> root = searchQuery.from(Student.class);
List<Predicate> restrictions = new ArrayList<>();

Subquery<Teacher> subQuery = searchQuery.subquery(Teacher.class);
Root<Teacher> fromSchoolSubQuery = subQuery.from(Teacher.class);
List<Predicate> subRestrictions = new ArrayList<>();

Subquery<School> subQuery2 = searchQuery.subquery(School.class);
Root<School> fromSchoolSubSubQuery = subQuery2.from(School.class);
List<Predicate> subSubRestrictions = new ArrayList<>();

subRestrictions.add(criteriaBuilder.equal(fromSchoolSubQuery.get(Social_number), userInput));
subRestrictions.add(criteriaBuilder.equal(fromSchoolSubQuery.get(School_ID), subQuery2.select(fromSchoolSubSubQuery.get(School_ID)).where(criteriaBuilder.equal(fromSchoolSubSubQuery.get(Student_ID), root.get(student_ID)))));

restrictions.add(criteriaBuilder.exists(subQuery.select(
fromSchoolSubQuery.get(Social_number)).where(
subRestrictions.toArray(new Predicate[0]))));

searchQuery.distinct(true)
            .select(root.get(name))
            .where( restrictions.toArray(new Predicate[restrictions.size()]) );

TypedQuery<String> query = em.createQuery(searchQuery)
List<String> nameList = query.getResultList();
所以我只需要在最后的
部分中用
中的
替换
=
。我在其他问题中发现了类似这样的问题:

CriteriaBuilder.In<String> in = criteriaBuilder.in( ??? );

在阅读本文第5章后,我找到了一个解决方案:

现在我们必须将
in
表达式添加到子限制中,这是通过
CriterisBuilder.in(…).value(subQueryForInExpression)
完成的:

CriteriaBuilder.In<String> in = criteriaBuilder.in( ??? );
Path<Object> path = root.get(student_ID);
CriteriaBuilder.In<Object> in = criteriaBuilder.in(path);
where teacher0_.school_id **in** (select school0_.id
from vnic03.school school0_
where school0_.student_id = student0_.id))) 
Subquery<School> subQueryForInExpression = searchQuery.subquery(School.class);
Root<School> fromSchoolSubQuery = subQueryForInExpression.from(School.class);

subQueryForInExpression.select(fromSchoolSubQuery.get(student_id)).where(criteriaBuilder.equal(fromSchoolSubQuery.get(school_id), root.get(student_id)));
select school0_.id
from vnic03.school school0_
where school0_.student_id = student0_.id
subRestrictions.add(criteriaBuilder.in(fromSchoolSubQuery.get(school_id)).value(subQueryForInExpression));