2011-08-01 68 views
9

的查询属性我有一个类的结构是这样的:JPA标准API:子类

@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: 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,我可以实现类似的东西?

+0

是不是缺少'builder.select(root)'?另外,您的条件查询不符合JPQL查询。 –

+0

感谢您的评论!嗯,我的'builder'(来自'hibernate-jpa-2.0-api-1.0.0.Final.jar')没有'select()'方法。是的,他们不相符,因为我很明显缺少;-)你是说我必须自己添加JOIN到'Article'吗? – msonntag

回答

1

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

也许你应该检查文章的类型是书。

我不知道如何使用CriteriaBuilder

Criteria c=session.createCriteria(CarItem.class, "caritem"); 
c.add(Restrictions.eq("caritem.class", Book.class)); 
List<Article> list=c.list(); 
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"); 
+0

工作就像一个魅力:) – wuerg