数据库
首页 > 数据库> > java – OpenJPA生成奇怪的SQL语句

java – OpenJPA生成奇怪的SQL语句

作者:互联网

OpenJPA生成以下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)

我刚加入几张桌子,最后做了

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源代码中找到了生成语句的位置.
我拍了调试会话的截图并标出了有趣的地方.

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

解决方法:

解决了

我终于在OpenJPA 2.2.1源代码中找到了导致生成这个奇怪语句的地方.

即使我的问题的原因位于我的代码中,解释非常有趣,
因为我从没想过OpenJPA会创建这样的声明.

当您在表达式中使用空的“in-values”集合创建SQL时,会发生这种情况.
例如:

Collection<String> usernames = .... // dynamically created 
                                    // (maybe by another query before)
Path<String> username = userJoin.get(User_.username);
Predicate usernamePredicate = username.in(usernames);

当usernames集合为空时,您将获得OpenJPA生成的奇怪SQL.
好的,如果用户名集合为空,则SQL-in表达式将评估为
假.
我认为OpenJPA开发人员希望让数据库优化器的生命更轻松
通过生成在这种情况下将评估为false的SQL表达式.
因此他们放置了

 CAST(1 AS INTEGER) <> CAST(1 AS INTEGER) 

在SQL语句中.

到目前为止,我可以理解目的是什么,但为什么他们不能创造生命
通过生成一个让我们知道它们生成原因的SQL,我们的开发人员也更容易
总是虚假的表达.
例如,如果它能够为人类提供有关正在发生的事情的信息(一个提示),那么该声明可以更加清晰.
例如:

 WHERE 'user.username in(emptyCollection)' IS NOT NULL;

这也总是错误的,但开发人员可能会理解问题所在.

标签:java,sql,openjpa
来源: https://codeday.me/bug/20190629/1326622.html