Hibernate &引用;Where query";在生产环境中创建错误的SQL

Hibernate &引用;Where query";在生产环境中创建错误的SQL,hibernate,grails,gorm,grails-2.3,Hibernate,Grails,Gorm,Grails 2.3,我必须将Spring从1.2.7更新到2.0,将Grails从2.2.0更新到2.3.11。在解决了几个典型的更新问题之后,我开始为测试服务器构建一个WAR。一切似乎都很好。但是在几次部署之后,我遇到了一个问题 有时(没有规则)服务器有100%的CPU使用率->OutOfMemeryError或应用程序抛出错误500。调试后,我注意到这些问题的原因是SQL查询不正确 其中查询: UserRole.find{role.authority =~ "%${authTxt}" && us

我必须将Spring从1.2.7更新到2.0,将Grails从2.2.0更新到2.3.11。在解决了几个典型的更新问题之后,我开始为测试服务器构建一个WAR。一切似乎都很好。但是在几次部署之后,我遇到了一个问题

有时(没有规则)服务器有100%的CPU使用率->OutOfMemeryError或应用程序抛出错误500。调试后,我注意到这些问题的原因是SQL查询不正确

其中查询:

UserRole.find{role.authority =~ "%${authTxt}" && user.id == currentUser.id}
创建这样的SQL:

select this_.id as id1_35_2_, this_.payment_enabled as payment_2_35_2_, this_.role_id as role_id3_35_2_, this_.user_id as user_id4_35_2_,
role_alias1_.id as id1_29_0_, role_alias1_.version as version2_29_0_, role_alias1_.authority as authorit3_29_0_, user_alias2_.id as id1_36_1_,
user_alias2_.version as version2_36_1_, user_alias2_.account_expired as account_3_36_1_, user_alias2_.account_locked as account_4_36_1_, 
user_alias2_.auto_password_flag as auto_pas5_36_1_, user_alias2_.email as email6_36_1_, user_alias2_.enabled as enabled7_36_1_, 
user_alias2_."password" as password8_36_1_, user_alias2_.password_expired as password9_36_1_, user_alias2_.user_info_id
as user_in10_36_1_, user_alias2_.username as usernam11_36_1_ from user_role this_ inner join role role_alias1_ on this_.role_id=role_alias1_.id inner join users user_alias2_ 
on this_.user_id=user_alias2_.id where (1=1 and 1=1)
下面是正确的SQL:

... inner join role role_alias1_ on this_.role_id=role_alias1_.id inner join users user_alias2_ on this_.user_id=user_alias2_.id 
where ((role_alias1_.authority ilike ?) and (user_alias2_.id=?)) 
明显的问题是表达式(1=1和1=1)。事实上,这种质疑:

User.findAll {id == userid} 
检索整个表动态查找程序或条件不会导致此问题。

我发现两个人有类似的问题:

我使用的插件:

  • spring安全核心:2.0-RC5
  • SpringSecurityOAuth:2.0.2
  • spring security oauth facebook:0.1
  • 冬眠:3.6.10.16
  • 执行人:0.3
  • 出口:1.6
  • csv:0.3.1
  • 数据库迁移:1.2.1
  • 石英:1.0-RC7
  • 资产管道:1.9.6
  • 圣杯旋律:1.57.0
数据库:PostgreSQL 8.4.20

我尝试了许多解决方案:

  • 我将Grails版本更改为2.4
  • 我把Hibernate3换成了Hibernate4
  • 我将连接器从9.0-801.jdbc3更改为9.1-901-1.jdbc4
  • 我删除了依赖项,以查看其中是否有任何依赖项不会导致问题
  • 我检查了提取的WAR是否在任何文件中都没有差异
  • 我更改了Java版本
  • 我改变了Tomcat的版本
  • 我在另一个系统上进行了测试
从我在博客上看到的上面的链接中,Graeme Rocher写道,问题可能是由于应用程序中缺少GORM。然而,在建立战争附属国的过程中,问题就出现了——附属国被错误地包装了(?)。但在这里,问题出现在解包或加载类时。从博客文章中寻找问题的根源,可以看出问题可能是由于一些荒谬的原因

有没有人知道是什么导致了这个问题,或者我可以调试什么来确定错误的来源?
grails开发人员的问题是:2.2版和2.3版之间发生了什么变化,理论上可能会导致这样的问题?

问题似乎来自于
grails数据存储gorm hibernate core
JAR中的
AbstractHibernateCriterionAdapter

标准适配器
哈希映射未正确填充

此映射是一个
最终静态HashMap
,用于将GORM标准映射到休眠标准

该问题在应用程序启动时随机出现。
有时填充HashMap没有任何问题,有时出现问题…
此Hashmap是静态final,在应用程序生命周期的剩余时间内一直处于损坏状态。这就是为什么你有时会遇到这个问题,重启后一切都很顺利

当多个线程同时创建
抽象HibernateCriterionadapter
对象时,HashMap可能会损坏。
每个线程都调用构造函数和
initialize()
方法。
此方法是
synchronized
,但
synchronized
习惯用法仅对访问同一对象的多个线程有效()

因此,
synchronized
无法正确锁定
initialize()
方法,多个线程可以尝试同时填充
准则适配器
哈希映射。
HashMap
不是线程安全的,因此HashMap会损坏,并且缺少一些标准

如果在此HashMap中未找到GORM标准,则该标准将被静默忽略。。。这就解释了为什么它会从生成的请求中消失


我创建了一个Github问题:

通过id以这种方式获取所有用户实例是一种奇怪的方式

你试过这个吗

User.findAllById(userid)

我们面临着类似的问题,无法应对。我们已经有3个查询停止“工作”,并被转换为失败的
,其中1=1和1=1
sql查询。不是同时!在服务器重新启动后的不同时刻,在发布后。这段代码在这一刻之前运行得非常好,几个月都没有运行过,并且在重新启动后再次运行。。。奇怪的,怪异的,还没有解决。三天前,我们遇到了一个大问题:一个查询本应只删除实体集合的一小部分,但却删除了整个集合。那是备份重新加载的一天。。。Grails2.4.4,Hibernate4与Grails2.4.4中的where查询存在相同的问题。查询应该取消过期成员,管理取消我们的整个用户群!这是非常不确定的,取决于应用程序如何启动。好吧,最后是这个问题的逻辑解释:)。但有一件事让我想知道为什么这个问题只发生在一些人身上?这不可能是Grails2.3/2.4中常见的问题。我又发现了一个规律,这个问题不会发生在虚拟机上……AbstractHibernateCriterionAdapter是在第一次执行criteria请求时填充的。因此,这可能取决于应用程序的第一个标准请求。如果在应用程序启动时同步执行两个请求(Bootstrap.groovy?),则可能会出现问题,否则就不可能出现此问题。它可以解释为什么只有一些应用程序受到影响。您需要任何进一步的信息来接受此响应吗?哦,对不起。谢谢你的帮助,这只是一个例子。主要问题在于,项目中的所有查询都会创建不正确的SQL。如果要执行联接,则该方法会在withcriteria闭包中使用Criteria联接。