Hibernate Subqueries.notIn错误地排除了结果

时间:2013-02-01 19:41:19

标签: hibernate subquery hibernate-criteria

在Hibernate方面,我相对比较绿色,但我面临调试看起来应该有效的Criteria查询。

数据结构大致如下:

User { Integer id, String type, String email, List<CustomerPolicy> policies, .... }  
CustomerPolicy { List<PolicyTable> tables, ... }  
PolicyTable { List<Insured> insureds, ... }  
Insured { Applicant applicant, ... }  
Applicant { String email, ... }  

我正在尝试在用户链接的CustomerPolicies上获取所有申请人的电子邮件列表,除了以获取与User表中现有的电子邮件匹配的电子邮件。

以下是我们在代码中的查询,但不起作用:


    emails.addAll(User.createCriteria().list() {
       eq("id", id)
       eq("type", "A")
       createAlias("policies", "policy")
       createAlias("policy.tables", "table")
       createAlias("table.insureds", "insured")
       createAlias("insured.applicant", "applicant")
       isNotNull("applicant.email")
       add(Subqueries.propertyNotIn("applicant.email", emailSubquery))
       projections {
           distinct("applicant.email")
       }
    })

    emailSubquery = DetachedCriteria.forClass(User).setProjection(Projections.property("email"))

我的用户有大约4个政策,每个政策有大约3-5个表格,每个表格至少有一个投保人和申请人,大约一半的申请人都有 的电子邮件用户表(alice@company.com)和另一半的用户表中的不是的电子邮件(foo@foo.com)。

随着emailSubquery的到位,没有任何电子邮件返回。删除子查询后,两者都返回。我已经确认foo@foo.com绝对不在User表中。

此查询有什么问题?

1 个答案:

答案 0 :(得分:0)

我假设您正在使用Oracle进行此查询,而这就是行为怪异的来源。

基本上,Oracle为其sql执行提供了优化编译器。 “不在”与“不存在”与“左连接”的详细信息在this article中有详细说明。

要将其缩小,使用propertyNotIn方法没有看到任何结果的原因是“user”表上的email属性包含null对象。这里的an example举例说明了您提供的架构的这种行为。

更合适的是,您要做的是使用 Subqueries.notExists 方法生成显示here的查询结果,这样即使存在空值也可以获得结果该栏中的价值。

祝福,希望这会有所帮助。

HT:SQL "select where not in subquery" returns no results