I am trying to use @Embeddable
with CriteriaBuilder
to filter results of a parent Entity
based on the embedded property. I use Eclipse Link to generate the Metadata classes.
Here is the embedded class/entity:
@Embeddable
public class Stamp implements Serializable {
@Basic()
@Column(name = "stamp_year", nullable = false)
private int year;
The parent class has the Stamp
as a member:
@Entity(name = "Message")
public class Message implements Serializable {
@Embedded
private Stamp stamp = new Stamp();
Now this code should use the Message
class and filter results based on the embedded class property year:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Message> cq = cb.createQuery(Message.class);
Root<Message> root = cq.from(Message.class);
Predicate p = cb.conjunction();
p = ??????
cq.where(p);
TypedQuery<Message> tq = em.createQuery(cq);
List<Message> messages = tq.getResultList();
On line 5 how do I get to the Message->Stamp->Year element of the query?
here are the generated metamodel classes:
@StaticMetamodel(Message.class)
public class Message_ {
public static volatile SingularAttribute<Message, Stamp> stamp;
and:
@StaticMetamodel(Stamp.class)
public class Stamp_ {
public static volatile SingularAttribute<Stamp, Integer> year;
Note: I removed all irrelevant information for code clarity but the full code is available on GitHub: prototype
The criteria based query may look as follows:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Message> cq = cb.createQuery(Message.class);
Root<Message> root = cq.from(Message.class);
Predicate p = cb.conjunction();
ParameterExpression<Integer> year = cb.parameter(Integer.class, "year");
p = cb.and(p, cb.equal(root.get(Message_.stamp).get(Stamp_.year), year));
cq.where(p);
TypedQuery<Message> tq = em.createQuery(cq).setParameter("year", 2015);
List<Message> messages = tq.getResultList();