JPA Criteria API: свойство запроса подкласса - PullRequest
9 голосов
/ 02 августа 2011

У меня есть такая структура классов:

@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?

Ответы [ 2 ]

1 голос
/ 15 августа 2014

У меня была та же проблема, и я нашел решение благодаря chris (см. API критериев JPA, где подкласс ).

Для этого вам нужен JPA 2.1, иВы используете один из методов CriteriaBuilder.treat().Просто замените builder.equal... строку на:

builder.equal(builder.treat(root.get("article"), Book.class).get("title"), "Foo");
1 голос
/ 21 апреля 2012

Я не эксперт, но с точки зрения ОО я бы сказал, что Статья не имеет названия свойства и, следовательно, не найдена в свойстве CarItem, названном article.

Возможно, вам следует проверить, относится ли статья к типу Book.

Я не уверен, как это сделать с помощью CriteriaBuilder

Criteria c=session.createCriteria(CarItem.class, "caritem");
c.add(Restrictions.eq("caritem.class", Book.class));
List<Article> list=c.list();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...