Hibernate &引用;Where query";在生产环境中创建错误的SQL
我必须将Spring从1.2.7更新到2.0,将Grails从2.2.0更新到2.3.11。在解决了几个典型的更新问题之后,我开始为测试服务器构建一个WAR。一切似乎都很好。但是在几次部署之后,我遇到了一个问题 有时(没有规则)服务器有100%的CPU使用率->OutOfMemeryError或应用程序抛出错误500。调试后,我注意到这些问题的原因是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
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
- 我将Grails版本更改为2.4
- 我把Hibernate3换成了Hibernate4
- 我将连接器从9.0-801.jdbc3更改为9.1-901-1.jdbc4
- 我删除了依赖项,以查看其中是否有任何依赖项不会导致问题
- 我检查了提取的WAR是否在任何文件中都没有差异
- 我更改了Java版本
- 我改变了Tomcat的版本
- 我在另一个系统上进行了测试
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联接。