Hi! I know we are very late, but we are starting t...
# questions
m
Hi! I know we are very late, but we are starting to take the first steps to move a Grails 2.5.5 application to Grails 7. The first thing we want to do is move all the before and after methods of the domains to services, since they are giving us a lot of problems with transactions. Do you think this is a good practice? How do you apply logic before and after the creation and update of instances of a domain? We make a lot of use of a customized dynamic scaffolding, based on the original Grails scaffolding. We want to make modifications to this scaffolding so that it will start using this "repository" service instead of direct calls to save method of the domain. Please, we would really appreciate your advice.
j
<https://grails.apache.org/docs/latest/grails-data/hibernate5/manual/index.html>
See the section: Events and Auto Timestamping
The grails docs have a wealth of information in them too - https://grails.apache.org/docs/latest - there is a whole section about scaffolding
I will say the biggest struggle you’re going to have is the update from 2 -> 3.3 Grails is massive. Unfortunately, no one wrote an upgrade guide for this since it’s so old =(
m
@jdaugherty sorry, let me explain it better. Currently we use gorm events a lot. Using them, we have errors like heuristic optimistic locking, row was updated while another transaction error, sometimes changes are not persisted without flush: true although is the last statement to be be performed before render... we have lost a lot of hours fighting this type of stuff. Also make changes to a domain class requires application restart. Our intention is to move the code we currently have in beforeInsert, afterInsert, beforeUpdate, afterUpdate and beforeDelete, to a centralized "repository" service that it could be used from the scaffolded controller and/or from an api controller we have for rest endpoints...
j
There's a lot to unpack here: 1. for reloading, the only "just works" solution is Jrebel. The other solutions sort of work, and depending on the project can function, but they're very troublesome. 2. I wouldn't be using the gorm events for those type of updates. I'd suggest you instead make use of Spring events to publish to a queue, and then annotate your services to listen for those events - so the gorm event just fires a spring event that's triggered on commit. This way, the event only fires once the transaction commits, which means you won't have a locking issue. 3. grails 2 & 3 had a LOT of issues. Graeme did an incredible amount of work on later versions. You'll probably find Grails 7 much better. One of the problems is people don't understand the difference in a session & transaction. Grails ultimately decided to make every session have a new transaction. That paradigm shift is significant. 4. Grails 2.x recommended
@Transactional
on controllers, but it was clear that was a bad idea. My general suggestion to you is make use of services and abstract validations, etc there. Treat domains as anemic & don't put complex validations in them.
m
Are Spring events you recommend the ones that makes use of publishEvent method and listeners stuff? We use them like it is explained on this article: https://www.tothenew.com/blog/using-spring-events-in-grails/ We use them in some parts of the project... and it seems sometimes events are lost. Now we have them configured synchronous and seems to work better... It is a big multitenant project (switchable datasource, and each tenant have a dedicated datasource) and I encourage the dev team to modernize it upgrading Grails instead of changing the framework, but we need to go ahead of these type of headaches.
j
I know there are numerous issues iwth multitenant that are set to be addressed in 7.0.8 (should release in the next week or so)
👏 1
I've never see events get lost, but i can see the datasource being a problem with multi-tenants. @James Fredley would know best here.
j
Grails 7.0.8 and 7.1.0 will include a lot of multi-tenant + multi-datasource changes that will be key to your app. I would go direct from 2.5.5 to 7, 4 to 6 is pretty simple, but 2 and 3 are challenging. Some of these old docs should also help: https://grails.apache.org/docs/3.0.0/guide/upgrading.html https://grails.apache.org/docs/3.1.0/guide/upgrading.html https://grails.apache.org/docs/3.2.0/guide/upgrading.html https://grails.apache.org/docs/3.3.0/guide/upgrading.html and https://github.com/sbglasius/initialGrails2Converter Having solid test coverage and crafting tests in ways that requires little to no changes across the grails version will help.
👍 3
m
Thank you double Js!!
👍 1
u
I wrote a blog-post with our experiences upgrading 2.4 to 3.3 several years ago: https://schneide.blog/2018/12/17/bringing-your-grails-app-from-2-4-to-3-3/. Maybe there is something helpful to be found there...