JPA Criteria API: query property of subclass

Viewed 8061

I have a class structure like this:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Article {
   private String aBaseProperty;
}

@Entity
public class Book extends Article {
   private String title;
}

@Entity
public class CartItem {
   @ManyToOne(optional = false)
   public Article article;
}

I tried the following to receive all CartItems that have a reference to a Book with title = 'Foo':

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<CartItem> query = builder.createQuery(CartItem.class);
Root<CartItem> root = query.from(CartItem.class);
builder.equal(root.get("article").get("title"), "Foo");
List<CartItem> result = em().createQuery(query).getResultList();

But unfortunately, this results in an error (makes sense to me, as title is in Book, not in Article...):

java.lang.IllegalArgumentException: Could not resolve attribute named title
    at org.hibernate.ejb.criteria.path.SingularAttributePath.locateAttributeInternal(SingularAttributePath.java:101)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:216)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:189)
...

However, I was able to achieve what I want using the following HQL:

SELECT c, a FROM CartItem c INNER JOIN c.article a WHERE a.title = ?

So why does the latter work and can I achieve something similar using the Criteria API?

2 Answers
Related