在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表中。
此查询有什么问题?
答案 0 :(得分:0)
我假设您正在使用Oracle进行此查询,而这就是行为怪异的来源。
基本上,Oracle为其sql执行提供了优化编译器。 “不在”与“不存在”与“左连接”的详细信息在this article中有详细说明。
要将其缩小,使用propertyNotIn方法没有看到任何结果的原因是“user”表上的email属性包含null对象。这里的an example举例说明了您提供的架构的这种行为。
更合适的是,您要做的是使用 Subqueries.notExists 方法生成显示here的查询结果,这样即使存在空值也可以获得结果该栏中的价值。
祝福,希望这会有所帮助。