JPA Criteria API:查询子类的属性 [英] JPA Criteria API: query property of subclass

查看:326
本文介绍了JPA Criteria API:查询子类的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的类结构:
$ b

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

@Entity
公共类书籍扩展条款{
private String title;
}

@实体
公共类CartItem {
@ManyToOne(可选= false)
公共文章文章;
}

我尝试了以下操作来接收所有 CartItems > Book Book with title ='Foo'

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery< CartItem> query = builder.createQuery(CartItem.class);
根< CartItem> root = query.from(CartItem.class);
builder.equal(root.get(article)。get(title),Foo);
列表< CartItem> result = em()。createQuery(query).getResultList();

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

 
java.lang.IllegalArgumentException:无法解析org.hibernate.ejb.criteria.path.SingularAttributePath.locateAttributeInternal(SingularAttributeInternal .java:101)
at org.hibernate.ejb.criteria.path.Abs​​tractPathImpl.locateAttribute(AbstractPathImpl.java:216)
at org.hibernate.ejb.criteria.path.Abs​​tractPathImpl.get(AbstractPathImpl .java:189)
...

然而,我能够使用以下HQL实现我想要的功能:

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

那么为什么后者能够工作,并且我可以使用Criteria API实现类似的功能?

解决方案

我有同样的问题,并且找到了解决方案,感谢 chris (请参阅 JPA Criteria API其中的子类)。 p>

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

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


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?

解决方案

I had the same issue and found a solution thanks to chris (see JPA Criteria API where subclass).

For this you need JPA 2.1, and you make use of one of the CriteriaBuilder.treat() methods. Just replace your builder.equal... line by:

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

这篇关于JPA Criteria API:查询子类的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆