I had to update Spring from 1.2.7 to 2.0, as well Grails from 2.2.0 to 2.3.11. After solving a few typical update problems, I started to build a WAR to the testing server. Everything seemed ok. But after a few deployments I encountered a problem.
Sometimes (there is no rule) the server has 100% CPU usage -> OutOfMemeryError or application throws error 500. After debugging, I noticed that the reason for these problems is incorrect SQL query.
Where query:
UserRole.find{role.authority =~ "%${authTxt}" && user.id == currentUser.id}
creates such 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)
and here the correct 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=?))
The obvious problem is that expression "(1 = 1 and 1 = 1)". In fact, such query:
User.findAll {id == userid}
retrieve the entire table. Dynamic finders or criteria does not cause this problem.
I found two people who had a similar issue:
https://zenofchicken.wordpress.com/2016/01/06/freaky-grails-where-clauses-dont-work-anymore/
http://grails.1312388.n4.nabble.com/Finder-not-applying-criteria-td4655689.html
Plugins that I use:
Database: PostgreSQL 8.4.20
I've tried many solutions:
From what I read on a blog which link I gave above, Graeme Rocher wrote that the problem may be due to a lack of GORM in the application. However, the problem was there during the building of WAR - dependencies were wrongly packed(?). But here the problem arises when WAR is unpacking or when classes are loading. Looking at the source of the problem from blog entry, shows that the problem may be due to some ridiculous reason ...
Does anyone have an idea what might cause this problem or what can I debug to be able to determine the source of the error? And the question to grails dev: what has changed between version 2.2 and 2.3 that theoretically could cause such a problem?
The problem seems to come from AbstractHibernateCriterionAdapter
in the grails-datastore-gorm-hibernate-core
JAR.
The criterionAdaptors
HashMap is not properly populated.
This map is a final static HashMap
used to map GORM Criterions to Hibernate ones.
The problem randomly occurs when the application starts.
Sometime the HashMap is populated without any problem, sometimes problem occurs...
This Hashmap is static final
and is kept corrupted for the rest of the application lifetime. That's why you sometime encounter this problem and everything goes well after a restart.
The HashMap can be corrupted when several threads are creating a AbstractHibernateCriterionAdapter
object at the same time.
Each thread calls the constructor and the initialize()
method.
This method is synchronized
but the synchronized
idiom is only effective for several threads accessing the same object (https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)
As a result, the synchronized
doesn't lock properly the initialize()
method and several threads can try to populate the criterionAdaptors
HashMap at the same time.HashMap
is not thread safe, as a result the HashMap gets corrupted and some Criterions are missing.
If a GORM Criterion is not found in this HashMap, the Criterion is silently ignored... Which explains why it disapears from the generated request.
I've created a Github issue : https://github.com/grails/grails-data-mapping/issues/643
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With