1

当谈到 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(“身份证”,身份证)
       eq(“类型”,“A”)
       createAlias(“政策”,“政策”)
       createAlias("policy.tables", "table")
       createAlias("table.insureds", "被保险人")
       createAlias("insured.applicant", "applicant")
       isNotNull("applicant.email")
       add(Subqueries.propertyNotIn("applicant.email", emailSubquery))
       预测{
           不同的(“申请人.email”)
       }
    })

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

我有一个用户有大约 4 个保单,每个保单大约有 3-5 个表格,每个表格至少有一个投保人,其中大约一半的申请人在用户表格 (alice@company.com) 中有一封电子邮件,并且另一半的电子邮件不在用户表 (foo@foo.com) 中。

使用 emailSubquery 后,没有任何电子邮件返回。删除子查询后,两者都返回。我已经验证 foo@foo.com 绝对不在 User 表中。

这个查询有什么问题?

4

1 回答 1

1

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

本质上,Oracle 为其 sql 执行提供了一个优化编译器。本文详细介绍了“不在”、“不存在”和“左连接”的详细信息。

归结起来,使用 propertyNotIn 方法看不到任何结果的原因是“用户”表上的电子邮件属性包含空对象。这是一个示例,说明了您提供的架构的这种行为。

更恰当地说,您要做的是使用Subqueries.notExists方法来生成此处显示的查询结果,这样即使该列中有空值,您也可以获得结果。

最良好的祝愿,希望这会有所帮助。

HT:SQL“选择不在子查询中的位置”不返回任何结果

于 2013-02-02T14:45:07.920 回答