Hibernate:条件查询未正确评估

发布于 2024-11-18 23:23:42 字数 2118 浏览 3 评论 0原文

我试图让以下查询在 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)
)

...as:

AND (m.obj2 IS NOT NULL 
     AND m.obj2.count > 0)

换句话说,它只返回满足 < 后面的条件的对象code>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"

没有自连接的相同查询不起作用。看似多余的括号也是如此。使用它们,它会返回错误的结果。

所以现在我的问题是,为什么有必要以这种方式构造查询,无论是自连接还是“多余的”括号?

值得注意的是,obj1obj2 是同一外部实体的不同实例。因此,我正在查询的表引用单个外部表中的两个不同行。我怀疑这就是为什么需要自连接的原因(也是我决定尝试自连接的原因),但我不确定其背后的确切原因是什么。任何解释都将受到欢迎。

I'm trying to get the following query to work in 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

The problem is, it seems to always evaluate the part that goes:

AND (
        m.obj1.count > 0
    OR 
        (m.obj2 IS NOT NULL 
         AND m.obj2.count > 0)
)

...as:

AND (m.obj2 IS NOT NULL 
     AND m.obj2.count > 0)

In other words, it is only returning objects that satisfy the condition that follows the OR, and ignoring any results that satisfy the first condition. If I remove the condition following the OR, the query correctly brings back objects that satisfy the m.obj1.count > 0 condition.

I assume I've made some basic error in how I have structured my query, but I'm not sure what it might be. Any ideas?

Update

I've found a variant that works, it uses a self-join and adds some superfluous parenthesis:

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"

This same query without the self-join does not work. Same goes for the seemingly superfluous parenthesis. With them, it returns an incorrect result.

So now my question is, why is it necessary to structure the query this way, both with respect to the self-join and the "superfluous" parenthesis?

It may be worth noting that obj1 and obj2 are different instances of the same foreign entity. So the table that I am querying is referencing two different rows in a single foreign table. I suspect that this is the reason why a self-join was necessary (and it is why I decided to try a self-join), but I'm not sure exactly what the reason behind it is. Any explanation would be welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼眸印温柔 2024-11-25 23:23:42

检查看起来没问题...你可以尝试这个详细的方法:

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

looks ok on inspection... you might try this verbose method:

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
秋意浓 2024-11-25 23:23:42

为了解决这个问题,我最终不得不修改我的查询,如下所示:

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

我感谢兰迪提出了很好的建议,但在我的具体情况下它不起作用,我不得不使用自连接重写我的原始查询,以便返回正确的结果。

To get around this issue I ultimately had to revise my query as follows:

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

I thank Randy for his very good suggestion, but in my specific case it did not work, and I had to rewrite my original query using a self-join in order to get the correct result back.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文