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与某个关联的 s 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)会产生相同的结果。

我使用 Hibernate 作为我的 JPA 实现,但我尝试坚持使用 JPA Criteria Queries。

4

1 回答 1

0

在 JPQL 中(我真的建议您在不需要动态生成的查询时使用它),您可以这样编写:

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

如果您真的想使用 Criteria API 来编写此查询,请执行相同的操作:创建一个连接并检查连接实体的 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 回答