jpaeclipselinkmetamodelembeddable

Use CriteriaBuilder on embedded object


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


Solution

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