我正在尝试让以下查询在Hibernate中工作:
SELECT m FROM MyEntity m WHERE m.owner = :user
AND m.field1 IN (:field1Vals)
AND m.field2 IN (:field2Vals)
AND m.obj1 IS NOT NULL
AND (
m.obj1.count > 0
OR
(m.obj2 IS NOT NULL
AND m.obj2.count > 0)
)
ORDER BY m.createDate DESC
问题是,它似乎总是在评估那部分:
AND (
m.obj1.count > 0
OR
(m.obj2 IS NOT NULL
AND m.obj2.count > 0)
)
...为:
AND (m.obj2 IS NOT NULL
AND m.obj2.count > 0)
换句话说,它只返回满足OR
之后条件的对象,并忽略满足第一个条件的任何结果。如果我删除OR
之后的条件,则查询会正确地返回满足m.obj1.count > 0
条件的对象。
我假设我在如何构建查询时遇到了一些基本错误,但我不确定它可能是什么。有什么想法吗?
更新
我发现了一个有效的变体,它使用自连接并添加了一些多余的括号:
SELECT DISTINCT m FROM MyEntity m, MyEntity m2 WHERE m.owner = :user
AND m.field1 IN (:field1Vals)
AND m.field2 in (:field2Vals)
AND m.obj1 IS NOT NULL
AND (
(m.obj1.count > 0)
OR
(m2.obj2 IS NOT NULL
AND (m2.obj2.count > 0))
)
ORDER BY m.createDate DESC"
没有自联接的同一查询不起作用。看似多余的括号也是如此。使用它们,它返回不正确的结果。
所以现在我的问题是,为什么有必要以这种方式构造查询,无论是关于自连接还是“多余”括号?
值得注意的是,obj1
和obj2
是同一外国实体的不同实例。所以我查询的表在一个外表中引用了两个不同的行。我怀疑这就是为什么自我加入是必要的(这就是我决定尝试自我加入的原因),但我不确定它背后的原因是什么。任何解释都会受到欢迎。
答案 0 :(得分:1)
在检查时看起来没问题......您可以尝试这种详细的方法:
SELECT m FROM MyEntity m WHERE m.owner = :user
AND m.field1 IN (:field1Vals)
AND m.field2 IN (:field2Vals)
AND m.obj1 IS NOT NULL
AND (
m.obj1.count > 0
)
union
SELECT m FROM MyEntity m WHERE m.owner = :user
AND m.field1 IN (:field1Vals)
AND m.field2 IN (:field2Vals)
AND m.obj1 IS NOT NULL
AND (m.obj2 IS NOT NULL
AND m.obj2.count > 0)
ORDER BY m.createDate DESC
答案 1 :(得分:0)
为了解决这个问题,我最终必须按如下方式修改我的查询:
SELECT DISTINCT m FROM MyEntity m, MyEntity m2 WHERE m.owner = :user
AND m.field1 IN (:field1Vals)
AND m.field2 in (:field2Vals)
AND m.obj1 IS NOT NULL
AND (
(m.obj1.count > 0)
OR
(m2.obj2 IS NOT NULL
AND (m2.obj2.count > 0))
)
ORDER BY m.createDate DESC
我感谢Randy提出的非常好的建议,但在我的具体情况下,它不起作用,我不得不使用自联接重写我的原始查询以获得正确的结果。