我试图在休眠状态下使用criteria
创建一个相关查询。
下面是代码:
预期的sql查询:
select * from
COLLEGE c
where (select count(s.college_id) from student s where c.college_id = s.college_id group by s.college_id)> 2;
但是它正在生成,外部学院( college0 _ )和子查询学院( college2_ <之间存在否 加入的条件/ strong>)
SELECT
college0_.COLLEGE_ID AS COLLEGE_1_2_,
college0_.NAME AS NAME2_2_
FROM
COLLEGE college0_
WHERE
(SELECT
COUNT(student1_.COLLEGE_ID)
FROM
STUDENT student1_
INNER JOIN
COLLEGE college2_ ON student1_.COLLEGE_ID = college2_.COLLEGE_ID
GROUP BY college2_.COLLEGE_ID) >= 3
执行相同操作的方法:
public List<College> findCollegesWithMoreThanXStudentsUsingCriteriaJpa(long x){
Session session = getSession();
CriteriaBuilder cb = session.getCriteriaBuilder();
String hql = " from College c where (select count(s.college) from Student s join s.college c1 where c.id = c1.id group by s.college) > :cnt"; // I am trying the same query using criteria
CriteriaQuery<College> collegeCriteriaQuery = cb.createQuery(College.class);
Root<College> collegeRoot = collegeCriteriaQuery.from(College.class);
collegeCriteriaQuery.select(collegeRoot);
Subquery<Long> subquery = collegeCriteriaQuery.subquery(Long.class);
Root<Student> studentRoot = subquery.from(Student.class);
subquery.select(cb.count(studentRoot.get("college")));
Join<College,Student> studentCollegeJoin = studentRoot.join("college");
subquery.correlate(collegeRoot);
subquery.groupBy(studentCollegeJoin.get("id"));
collegeCriteriaQuery.where(cb.greaterThanOrEqualTo(subquery,x));
return session.createQuery(collegeCriteriaQuery).getResultList();
}
实体类:
Student.java
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.List;
@Entity
@Table(name = "STUDENT")
public class Student {
@Id
@Column(name = "STUDENT_ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="NAME")
private String name;
@ManyToOne
@JoinColumn(name = "COLLEGE_ID",referencedColumnName = "COLLEGE_ID")
private College college;
@OneToMany(cascade = {CascadeType.ALL})
@JoinColumn(name = "STUDENT_ID",referencedColumnName = "STUDENT_ID")
private List<StudentAddress> studentAddresses;
public int getId() {
return id;
}
public Student setId(int id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public College getCollege() {
return college;
}
public Student setCollege(College college) {
this.college = college;
return this;
}
public List<StudentAddress> getStudentAddresses() {
return studentAddresses;
}
public Student setStudentAddresses(List<StudentAddress> studentAddresses) {
this.studentAddresses = studentAddresses;
return this;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", college=" + college +
", studentAddresses=" + studentAddresses +
'}';
}
}
College.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "COLLEGE")
public class College {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "COLLEGE_ID")
private int id;
@Column(name = "NAME")
private String name;
public int getId() {
return id;
}
public College setId(int id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public College setName(String name) {
this.name = name;
return this;
}
@Override
public String toString() {
return "College{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
答案 0 :(得分:2)
这里不需要correlate
,因为这里没有使用外部查询的任何值。您需要的是将子查询与外部查询结合起来
subquery.where(cb.equal(collegeRoot.get("id"), studentCollegeJoin.get("id")));