我正在尝试让以下查询在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
是同一外部实体的不同实例。因此,我正在查询的表引用了一个外部表中的两个不同行。我怀疑这就是为什么自我加入是必要的(这也是我决定尝试自我加入的原因(,但我不确定背后的确切原因是什么。欢迎任何解释。
检查时看起来不错。。。您可以尝试这种详细的方法:
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
为了解决这个问题,我最终不得不修改我的查询如下:
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提出的非常好的建议,但在我的特定情况下,它不起作用,我不得不使用自联接重写我的原始查询,以获得正确的结果。