JPA Criteria API查询子类属性 [英] JPA criteria API query subclass property

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

问题描述

我要执行与特定子类属性匹配的查询,因此我尝试使用treat()

在本例中,我希望:

名称以‘a’开头的所有主题
或所有主题,即姓氏以‘a’开头的人

private List<Subject> q1()
{
    CriteriaBuilder b = em.getCriteriaBuilder();

    CriteriaQuery<Subject> q = b.createQuery(Subject.class);
    Root<Subject> r = q.from(Subject.class);
    q.select(r);
    q.distinct(true);
    q.where(
        b.or(
            b.like(r.get(Subject_.name), "a%"),
            b.like(b.treat(r, Person.class).get(Person_.lastName), "a%")));

    return em.createQuery(q).getResultList();
}

显然,Person扩展SubjectSubject是抽象的,继承是SINGLE_TABLESubject有其他原因(不传入)。

但生成的SQL如下:

select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.DTYPE='Person' and (subject0_.name like 'a%' or subject0_.lastName like 'a%')

当我怀孕时:

select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.name like 'a%' or (subject0_.DTYPE='Person' and subject0_.lastName like 'a%')

是否有办法使用条件生成器生成预期的查询?

请注意

  • 使用另一个-q.from(Person.class)
  • 使用子查询-q.subquery(Person.class)
  • 姓氏字段上移到主题
  • 使用本地查询
  • 使用实体图

不可接受

我感兴趣的是可以直接在WHERE子句中声明和使用的内容(仅从CriteriaBuilder和/或单个Root生成,就像treat()子句一样)。

推荐答案

解决方案是使用Hibernate,在此特定场景中非常简单:

private List<Subject> q1()
{
    CriteriaBuilder b = em.getCriteriaBuilder();

    CriteriaQuery<Subject> q = b.createQuery(Subject.class);
    Root<Subject> r = q.from(Subject.class);
    q.select(r);
    q.distinct(true);
    q.where(
        b.or(
            b.like(r.get(Subject_.name), "a%"),
            b.and(
                b.equal(r.type(), Person.class),
                b.like(((Root<Person>) (Root<?>) r).get(Person_.lastName), "a%"))));

    return em.createQuery(q).getResultList();
}

注意双重转换,它避免了编译错误,并允许在同一个表上执行查询子句。这将生成:

select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.DTYPE in ('Office', 'Team', 'Role', 'Person', ...) 
    and (subject0_.name like 'a%' 
        or subject0_.DTYPE='Person' and (subject0_.lastName like 'a%'))

不需要更改模型或其他任何内容。

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

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