OpenJPA 生成以下 where sql 部分
WHERE (t3.USERNAME = ? AND CAST(1 AS INTEGER) <> CAST(1 AS INTEGER)
AND t5.USERNAME IS NOT NULL AND 1 = 1 AND 1 = 1 AND 1 = 1)
我刚刚加入了几张 table ,终于做到了
Join<SomeEntity, User> userJoin = someJoin.join(SomeEntity_.user);
Path<String> usernamePath = userJoin.get(User_.username);
CriteriaBuilder cb = getCb();
Predicate usernamePredicate = cb.equal(usernamePath, username);
JPA发送到数据库的sql中奇怪的部分是
CAST(1 AS INTEGER) <> CAST(1 AS INTEGER)
这个表达式永远是假的。所以永远不会有用户被选中。
好的,还有
1 = 1 AND 1 = 1 AND 1 = 1
表达式真的很奇怪,但是数据库的查询优化器应该删除它们 永远是真的。
- 是否有人拥有由 OpenJPA 生成的相同或相似的奇怪 sql 语句?
- 谁能告诉我(希望是 OpenJPA 开发人员)为什么要使用 OpenJPA 生成如此奇怪的语句?
研究继续
今天在OpenJPA 2.2.1源码中找到了生成该语句的地方。 我截取了调试 session 的屏幕截图并标记了有趣的地方。
放大1 : http://i.stack.imgur.com/LBmzM.png
最佳答案
已解决
我终于在 OpenJPA 2.2.1 源代码中找到了导致生成此奇怪语句的位置。
即使我的问题的原因位于我的代码中,解释也很有趣, 因为我从没想过 OpenJPA 会创建这样的声明。
当您使用空的“in-values”集合创建 SQL in 表达式时,就会发生这种情况。 例如:
Collection<String> usernames = .... // dynamically created
// (maybe by another query before)
Path<String> username = userJoin.get(User_.username);
Predicate usernamePredicate = username.in(usernames);
当用户名集合为空时,您会得到 OpenJPA 生成的奇怪 SQL。 好的,如果用户名集合为空,则 SQL-in 表达式将计算为 错误的。 我认为 OpenJPA 开发人员希望让数据库优化器的工作更轻松 通过生成一个 SQL 表达式,在这种情况下,该表达式的计算结果将永远为 false。 因此他们放置了
CAST(1 AS INTEGER) <> CAST(1 AS INTEGER)
在 SQL 语句中。
到目前为止我能理解目的是什么,但为什么他们不能创造生活 通过生成一个让我们知道他们为什么生成的 SQL,我们开发人员也更容易 总是错误的表达。 例如,如果它能为人类提供有关正在发生的事情的信息(提示),那么该陈述可能会更加清晰。 例如:
WHERE 'user.username in(emptyCollection)' IS NOT NULL;
这也总是错误的,但开发人员可能会理解问题所在。
关于java - OpenJPA 生成奇怪的 SQL 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17300067/