Hibernate标准按相关实体过滤

时间:2013-01-20 07:26:24

标签: java hibernate java-ee criteria-api

我有一个拥有相关实体集合的实体。

public class Student{

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "COURSE_STUDENT_ID" , insertable=false,updatable=false)
private Set <Course> courses;

我想按课程名称和学生班级ID过滤学生。现在我已经解决了如何按类ID进行过滤但我不知道如何根据courseId过滤,因为Student实体有一组课程并且表是相关的。我已经阅读了一些文章,但没有任何代码与我已有的代码相匹配。

CriteriaBuilder criteriaBuilder = persistenceStore.createCriteriaBuilder();
CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
Root<Student> root = criteria.from(Student.class);
List<Predicate> params = new ArrayList<Predicate>();

params.add(criteriaBuilder.equal(root.get("classId"),classId));

Predicate[] predicates = new Predicate[params.size()];
params.toArray(predicates);
criteria.select(root);
criteria.where(criteriaBuilder.and(predicates));
Query query = persistenceStore.createQuery(criteria);
List<Student> resultList = query.getResultList();

2 个答案:

答案 0 :(得分:3)

首先,您的实体中存在错误:JoinColumn注释适用于关系反面的实体,Course

因此,如果Course实体具有属性student,则Student具有以下属性:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "student")
private Set<Course> courses;

并且在您拥有的课程实体中(此处还说明在数据库中,表课程有一个名为&#34的字段;学生&#34;:

@JoinColumn(name = "student", referencedColumnName = "id")
@ManyToOne(optional = false)
private Student student;

阅读this link,了解如何映射实体关系的入门级解释。

关于Criteria Query,由于您想要检索Student S的List,您可以以更安全的方式定义CriteriaQuery:

CriteriaQuery<Student> criteria = criteriaBuilder.createQuery(Student.class);

关于这个问题,你必须以这种方式加入表格:

SetJoin<Student, Course> courses = root.join("courses");

或使用MetaModel:

SetJoin<Student, Course> courses = root.join(Student_.courses);

(如果OneToMany属性已定义为ListCollection,则您必须使用相应的ListJoinCollectionJoin类。

在课程中您可以应用所需的Predicate条件(假设课程实体具有名为courseName的字符串属性):

Predicate p = criteriaBuilder.equal(courses.get("courseName"), "name-to-look-for");

或使用Metamodel:

Predicate p = criteriaBuilder.equal(courses.get(Course_.courseName), "name-to-look-for");

最后,为了正确连接谓词列表,您可以使用(至少)两种技术:

Predicate p1 = ...;
Predicate p2 = ...;

criteria.where(criteriaBuilder.and(p1, p2));

List<Predicate> conditions = new ArrayList<Predicate> ();
conditions.add(p1);
conditions.add(p2);
criteria.where(conditions.toArray(new Predicate[] {}));

另见这篇优秀的article

答案 1 :(得分:-1)

类型不匹配:无法从cascadetype转换为cascadetype []

答案是:

import javax.persistence.CascadeType;

导入此行