4

関連するエンティティのコレクションを持つエンティティがあります。

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 でフィルタリングする方法を考え出しましたが、Student エンティティに一連のコースがあり、テーブルが関連していることを考えると、courseId でフィルタリングする方法がわかりません。いくつかの記事を読みましたが、既に持っているものと一致するコードはありません。

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();
4

2 に答える 2

6

まず、エンティティにエラーがあります。あなたの場合、JoinColumn注釈は関係の逆側のエンティティに適用さCourseれます。

したがって、Courseエンティティにプロパティがある場合student、学生には次のようなプロパティがあります。

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

あなたが持っているCourseエンティティでは(ここでは、データベースにコーステーブルに「学生」というフィールドがあることも述べています:

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

エンティティ関係をマッピングする方法についての入門レベルの説明については、このリンクを参照してください。

Criteria クエリに関しては、StudentS のリストを取得する必要があるため、CriteriaQuery をよりタイプ セーフな方法で定義できます。

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

質問に関しては、次の方法でテーブルを結合する必要があります。

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

または、MetaModel を使用して:

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

List(OneToMany プロパティがまたはとして定義されCollectionていた場合、対応するListJoinおよびCollectionJoinクラスを使用する必要がありました)。

コースでは、必要な条件を適用できますPredicate( Course エンティティに という文字列プロパティがあると仮定しますcourseName):

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

または、メタモデルを使用して:

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

最後に、述語のリストを正しく連結するために、(少なくとも) 2 つの手法を使用できます。

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[] {}));

この優れた記事も参照してください。

于 2013-01-20T09:32:47.180 に答える