0

エンティティがあるとします

@Entity
public class Test {
   @ManyToMany
   @JoinTable(..etc..)
   private List<Subject> subjects; // School subjects this test is associated with
   ....

そしてエンティティ

@Entity
public class Exam extends Test {
   // Inherits subjects from test
   // Does some things specific to exams
   ...

Examそして、特定の に関連付けられた のみを取得する基準クエリ (メタモデルを使用) を作成したいと考えていますSubject。私の質問は、このクエリをどのように書くのですか?

私が試したことは次のとおりです。

私が書いたら

    CriteriaBuilder cb = em.getCriteriaBuilder();  // em is the EntityManager
    CriteriaQuery<Exam> cq = cb.createQuery(Exam.class);
    Root<Exam> root = cq.from(Exam.class);

    cq.where(cb.isMember(subject, root.get(Exam_.subjects)));

    return em.createQuery(cq);

コンパイラはそれをコンパイルしませんerror: no suitable method found for get(ListAttribute<Test,Subject>)。直観的にはこれが解決策であるかのように感じますが、継承は十分ではありません。クエリでメタモデル参照を省略して に置き換えても機能しませんroot.get("subjects")

私が書いたら

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Exam> cq = cb.createQuery(Exam.class);
Root<Test> root = cq.from(Test.class);

cq.where(cb.isMember(subject, root.get(Exam_.subjects)));

return em.createQuery(cq);

これは間違っているように感じますが、コンパイルされます。ただし、実際にコードを実行すると、例外が表示されます。IllegalStateException: No explicit selection and an implicit one could not be determinedこれは、 の型をジャグリングした結果として解釈しRootます。試しroot.get(Test_.subjects)ても同じ結果になります。

私は JPA 実装として Hibernate を使用していますが、JPA Criteria Queries に固執しようとしています。

4

1 に答える 1

0

JPQL(動的に生成されたクエリが必要ない場合に使用することをお勧めします)では、次のように記述します。

select e from Exam e
inner join e.students student
where student.id = :studentId

本当にCriteriaAPIを使用してこのクエリを記述したい場合は、同じことを行います。結合を作成し、結合されたエンティティのIDが指定された学生IDと等しいことを確認します。次のようになります。

Join<Exam, Student> studentJoin = root.join(Exam_.students);
cq.where(qb.equal(studentJoin.get(Student_.id), student.getId());
于 2013-02-20T23:03:59.873 に答える