gpt4 book ai didi

java - OpenJPA 生成奇怪的 SQL 语句

转载 作者:搜寻专家 更新时间:2023-11-01 03:07:32 24 4
gpt4 key购买 nike

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

表达式真的很奇怪,但是数据库的查询优化器应该删除它们永远是真的。

  1. 是否有人拥有由 OpenJPA 生成的相同或相似的奇怪 sql 语句?
  2. 谁能告诉我(希望是 OpenJPA 开发人员)为什么要使用 OpenJPA生成如此奇怪的语句?

研究继续

今天在OpenJPA 2.2.1源码中找到了生成该语句的地方。我截取了调试 session 的屏幕截图并标记了有趣的地方。

放大1 : http://i.stack.imgur.com/LBmzM.png

enter image description here

最佳答案

已解决

我终于在 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com