Say I have an entity
@Entity
public class Test {
@ManyToMany
@JoinTable(..etc..)
private List<Subject> subjects; // School subjects this test is associated with
....
And an entity
@Entity
public class Exam extends Test {
// Inherits subjects from test
// Does some things specific to exams
...
And I want to write a criteria query (with metamodels) that gives me only the Exam
s associated with a certain Subject
. My question is: how do I write this query?
What I've tried is the following:
If I write
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);
the compiler won't compile it, saying error: no suitable method found for get(ListAttribute<Test,Subject>)
. Intuitively it feels as if this should be the solution, but inheritance won't go far enough. It won't work either if I omit the metamodel reference in the query and replace it with root.get("subjects")
.
If I write
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);
This feels wrong, but it does compile. However, upon actually executing the code I am presented with an exception: IllegalStateException: No explicit selection and an implicit one could not be determined
which I interpret as a consequence of juggling around the types for the Root
. Trying root.get(Test_.subjects)
yields the same result.
I use Hibernate as my JPA implementation, but I try to stick to JPA Criteria Queries.