I'm performing the following logic on a single Service
in grails 2.4.4.
class SampleService {
void process(params1, params2) {
SampleDomain1 sd1 = new SampleDomain1()
sd1.setProperties(params1)
sd1.save()
SampleDomain2 sd2 = new SampleDomain2()
sd2.setProperties(params2)
sd2.save()
}
}
What I understand is that Service
s are by default transactional. If sd1.save()
is successful but sd2.save()
is not, it will rollback the changes and will throw an error. While if both are successful, both are committed upon service's exit.
If my understanding is correct, then both of it should already been persisted to the database. However, the problem is: it does not— unless if you explicitly use the flush: true
parameter based on my tests using the same set of params1
and params2
.
sd1.save(flush: true)
SampleDomain2 sd2 = new SampleDomain2()
sd2.setProperties(params2)
sd2.save(flush: true)
}
Which, by the way is what I am really avoiding (what would be the point setting it as @Transactional
). If that's the catch of Hibernate 4 / Grails 2.4, what do I need to do to make my services to commit at every end of a service call again? Do I need to configure any global configuration of Grails? I really need to flush my Domain classes at the end of every service automatically.
I've already assured that the data is correct, including calling .validate()
and other checker. Success in performing .save(flush: true)
proves that. The problem I found is regarding to the update on Grails 2.4 on its FlushMode
. Now, maybe what I really need is a global settings to override this.
Somewhere on my DataSource.groovy
configuration, there is this line:
hibernate {
...
singleSession = true // configure OSIV singleSession mode
flush.mode = 'manual' // OSIV session flush mode outside of transactional context
^^^^^^^^^^
}
Which explicit states that every save should be flushed manually. As a solution, I comment out this line. After that, every database transaction now commits every time it exists a Service
.