Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate JPA criteria API查询子类属性_Hibernate_Jpa_Inheritance_Criteria_Criteria Api - Fatal编程技术网

Hibernate JPA criteria API查询子类属性

Hibernate JPA criteria API查询子类属性,hibernate,jpa,inheritance,criteria,criteria-api,Hibernate,Jpa,Inheritance,Criteria,Criteria Api,我想执行一个与特定子类属性匹配的查询,所以我尝试使用treat() 在本例中,我希望: 名称以“a”开头的所有受试者, 或所有受试者,均为人,姓氏以“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

我想执行一个与特定子类属性匹配的查询,所以我尝试使用
treat()

在本例中,我希望:

名称以“a”开头的所有受试者,
或所有受试者,均为人,姓氏以“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%')
有没有一种方法可以使用criteria builder生成预期的查询?

注意

  • 使用另一个根目录-
    q.from(Person.class)
  • 使用子查询-
    q.subquery(Person.class)
  • 将lastName字段向上移动到Subject
  • 使用本机查询
  • 使用实体图
是不可接受的


我对WHERE子句中可以直接声明和使用的内容感兴趣(仅由CriteriaBuilder和/或单根生成,就像
treat()
子句),如果它确实存在的话。

更新:

您期望的sql—虽然可以使用纯jpa crtieria api生成—但它不会工作,并且会引发异常,因为您(hibernate)无法实例化抽象类主题

原因:org.hibernate.InstantiationException:无法实例化 抽象类或接口:

如果类不是抽象的,它就可以工作。像这样:

CriteriaBuilder b = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Contact> q;
q = b.createQuery(Contact.class);
Root r = q.from(Contact.class);

   q.select(r);
   q.distinct(true);
q.where(
        b.or(
                b.like(r.get(Contact_.name),"t%"),
                b.and(
                        b.equal(r.get(Contact_.contact_type),"customer"),
                        b.like(r.get(Customer_.lastName),"t%")
                )
        )
);

return getEntityManager().createQuery(q).getResultList();
然后作为抽象类与customer联系,作为子类,如下所示:

CriteriaBuilder b = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Contact> q = b.createQuery(Contact.class);
           Root<Contact>  r = q.from(Contact.class);
           q.distinct(true);

           q.where(
                b.or(
                        b.like(r.get(Contact_.name), "t%"),
                        b.and(
                                b.equal(r.get(Customer_.contact_type), "customer"),
                                b.like(r.get(Customer_.name), "%t")
                        )
                )
                );
           return getEntityManager().createQuery(q).getResultList();

使用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();
}

无需更改型号或其他任何内容。

您正在访问Customer\ux.name,该名称与Contact\ux.name相同。如果使用在Customer上定义的属性并导致方法get的编译错误,则该方法将不起作用(SingularAttributes请查看我的更新,如果您知道没有发生问题的根的类型。您正在处理与元模型查询转换无关的事情…但是您的更新为我指明了正确的方向。尽管不值得赏金或接受,但仍然值得几次+1。谢谢。
@Column(name = "contact_type",insertable = false,updatable = false)
@XmlTransient
private String contact_type;
CriteriaBuilder b = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Contact> q = b.createQuery(Contact.class);
           Root<Contact>  r = q.from(Contact.class);
           q.distinct(true);

           q.where(
                b.or(
                        b.like(r.get(Contact_.name), "t%"),
                        b.and(
                                b.equal(r.get(Customer_.contact_type), "customer"),
                                b.like(r.get(Customer_.name), "%t")
                        )
                )
                );
           return getEntityManager().createQuery(q).getResultList();
select

distinct contact0_.id as id2_1_,
    contact0_.contact_type as contact_1_1_,
    contact0_.name as name3_1_ 
from
    Contact contact0_ 
where
    contact0_.name like ? 
    or contact0_.contact_type=? 
    and (
        contact0_.name like ?
    )
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%'))