Search code examples
grailsgrails-ormtransactional

Grails do not commit after a successful service call


I'm performing the following logic on a single Service in 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 Services 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.


Note

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.


Solution

  • 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.