У меня есть такая структура классов:
@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;
}
Я попробовал следующее, чтобы получить все CartItems
, которые имеют ссылку на Book
с 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();
Но, к сожалению, это приводит к ошибке (имеет смысл для меня, поскольку title
в Book
, а не в 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)
...
Однако я былсмог достичь того, что я хочу, используя следующий HQL:
SELECT c, a FROM CartItem c INNER JOIN c.article a WHERE a.title = ?
Так почему же работает последний и можно ли добиться чего-то подобного с помощью API Criteria?