【问题标题】:JPA Criteria API: query property of subclassJPA Criteria API:查询子类的属性
【发布时间】:2011-10-17 17:48:21
【问题描述】:

我有一个这样的类结构:

@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;
}

我尝试了以下方法来接收所有引用Booktitle = 'Foo'CartItems

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

但不幸的是,这会导致错误(对我来说很有意义,因为 titleBook 中,而不是在 Article...):

java.lang.IllegalArgumentException:无法解析名为标题的属性 在 org.hibernate.ejb.criteria.path.SingularAttributePath.locateAttributeInternal(SingularAttributePath.java:101) 在 org.hibernate.ejb.criteria.path.Abs​​tractPathImpl.locateAttribute(AbstractPathImpl.java:216) 在 org.hibernate.ejb.criteria.path.Abs​​tractPathImpl.get(AbstractPathImpl.java:189) ...

但是,我能够使用以下 HQL 实现我想要的:

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

那么为什么后者会起作用,我可以使用 Criteria API 实现类似的效果吗?

【问题讨论】:

  • 你不缺builder.select(root)吗?另外,您的条件查询与 JPQL 查询不对应。
  • 感谢您的评论!嗯,我的builder(来自hibernate-jpa-2.0-api-1.0.0.Final.jar)没有select() 方法。是的,它们不对应,因为我显然错过了某事;-) 你是说我必须自己将 JOIN 添加到 Article 吗?

标签: sql hibernate jpa polymorphism criteria


【解决方案1】:

感谢chris,我遇到了同样的问题并找到了解决方案(请参阅JPA Criteria API where subclass)。

为此,您需要 JPA 2.1,并使用 CriteriaBuilder.treat() 方法之一。只需将您的 builder.equal... 行替换为:

builder.equal(builder.treat(root.get("article"), Book.class).get("title"), "Foo");

【讨论】:

  • 工作就像一个魅力:)
【解决方案2】:

我不是专家,但从 OO 的角度来看,我会说文章没有属性标题,因此在 CarItem 的名为 article 的属性中找不到。

也许你应该检查一下 Article 是否属于 Book 类型。

我不确定如何使用 CriteriaBuilder 执行此操作

Criteria c=session.createCriteria(CarItem.class, "caritem");
c.add(Restrictions.eq("caritem.class", Book.class));
List<Article> list=c.list();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2012-01-29
    • 1970-01-01
    • 2017-07-20
    相关资源
    最近更新 更多