简体   繁体   English

通过子查询缩小查询结果

[英]Narrowing the result of query by subquery

I'm trying to narrow the result set of Hibernate Criteria query by result of another query. 我试图通过另一个查询的结果缩小Hibernate Criteria查询的结果集。 I know how to resolve this problem with JPQL: 我知道如何用JPQL解决这个问题:

FROM DocPackage p WHERE
  EXISTS (SELECT g
    FROM ObjectGroup g JOIN g.items i, Person per
    WHERE g=p.applicantGroup
      AND i.objectClass = 'org.cp.model.common.Person'
      AND i.objectId=per.id
      AND lower(concat(per.firstName,' ',per.lastName)) like :applicant
  )

But I can't imagine how to make such query with Criteria. 但我无法想象如何使用Criteria进行此类查询。 Any ideas how to implement this selection with Criteria? 有关如何使用Criteria实现此选择的任何想法? Hibernate 3.3 is used. 使用Hibernate 3.3。

UPD: Trying to solve this problem I've made the following Criteria query: UPD:试图解决这个问题我做了以下Criteria查询:

Criteria resultCriteriaQuery = this.hibernateSession.createCriteria(DocPackage.class, "pack");
        DetachedCriteria personSubquery = DetachedCriteria.forClass(Person.class, "pers").
            add(Restrictions.like("pers.loFstLstName", "%" + searchObject.getApplicant().toLowerCase() + "%")).
            add(Restrictions.eqProperty("itm.objectId", "pers.id"));
        DetachedCriteria applicantsSubquery = DetachedCriteria.forClass(ObjectGroup.class, "objGrp").
            add(Restrictions.eqProperty("pack.applcantGroup", "objGrp")).
            createAlias("objGrp.items", "itm").
            add(Restrictions.eq("itm.objectClass", "org.cp.model.common.Person")).
            add(Subqueries.exists(personSubquery));
        resultCriteriaQuery.add(Subqueries.exists(applicantsSubquery));

But it doesn't work. 但它不起作用。 I have a NullPointerException on resultCriteriaQuery.list() . 我在resultCriteriaQuery.list()上有一个NullPointerException What's wrong with this query? 这个查询出了什么问题? Any ideas? 有任何想法吗?

to analyze the case a little better, it prints the HQL statement generated automatically from the criteria, you have to put in the connection properties hibernate: 为了更好地分析案例,它会打印从条件自动生成的HQL语句,你必须在连接属性hibernate中输入:

<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />

And the log to debug. 和日志调试。

Once you have it, you can compare with which you want to generate and view the differences. 获得后,您可以与要生成的内容进行比较并查看差异。

Regards, 问候,

You can create sub-criteria with the Criteria.createCriteria(String) method. 您可以使用Criteria.createCriteria(String)方法创建子标准。

Assuming the following scenario: 假设以下情形:

Class B has a name:String. B类的名称为:String。

Class A has a elements:Set. A类有一个元素:Set。

You now want (apart from other restrictions) only A-objects where there is one B with name="X": 您现在想要(除了其他限制)只有A对象,其中有一个B,名称=“X”:

Criteria crit = session.createCriteria(A.class);
<add your restrictions for A>

Criteria narrow = crit.createCriteria("elements");
narrow.add(Restrictions.eq("name", "X");

// This will respect the constraints applied to narrow
crit.list();

Non-associated joins are not supported by Hibernate Criteria API. Hibernate Criteria API不支持非关联联接。 This row is a problem: 这一行是个问题:

FROM ObjectGroup g JOIN g.items i, Person per

From what I see, you'll need to create an explicit mapping between ObjectGroupItem and Person. 从我看到的,你需要在ObjectGroupItem和Person之间创建一个显式映射。 This may be accomplished by the means of Hibernate @Any annotation. 这可以通过Hibernate @Any注释来实现。 Take a look at Hibernate Annotations , paragraph 2.4.5.2. 看看Hibernate Annotations ,第2.4.5.2节。 When association will be mapped, use Criteria#createCriteria() or Criteria#createAlias() to add necessary joins to the sub query. 在映射关联时,使用Criteria#createCriteria()或Criteria#createAlias()向子查询添加必要的连接。 You are already using correct API to add a subquery to the main query. 您已使用正确的API将子查询添加到主查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM