Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"No transaction is in progress" error while following Grails Spring Security Core tutorial

I'm following the Grails Spring Security Core tutorial in their documentation. When I reach 24.1.5.5, the problems start. I'm instructed to modify Bootstrap.groovy to the following, then run the app:

package com.mycompany.myapp

class BootStrap {

   def init = {

         def adminRole = new Role(authority: 'ROLE_ADMIN').save()

         def testUser = new User(username: 'me', password: 'password').save()

         UserRole.create testUser, adminRole

         UserRole.withSession {
            it.flush()
            it.clear()
         }

         assert User.count() == 1
         assert Role.count() == 1
         assert UserRole.count() == 1

   }
}

Running the app gives me this error:

2020-03-31 15:46:19.294 ERROR --- [ restartedMain] o.s.boot.SpringApplication : Application run failed

javax.persistence.TransactionRequiredException: no transaction is in progress at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl .java:3586)

I've attempted to use @Transactional to solve this, but it had no impact on the error. Reverting Bootstrap.groovy to its default allows the application to run normally. What is missing (or incorrect) from this tutorial that is causing it to fail?

like image 806
Fibericon Avatar asked Dec 17 '22 13:12

Fibericon


2 Answers

The documentation is out of date. Hibernate 5.2+ requires transactions for write operations now. Adding the @Transactional did not work because init is a closure and the annotation applies to methods or classes.

Create a new method in bootstrap and add transactional to it. then call it from your init closure. For example.

class BootStrap {

    def init = {
        addTestUsers()
    }

    @Transactional
    void addTestUsers() {
        def adminRole = new Role(authority: 'ROLE_ADMIN').save()

        def testUser = new User(username: 'me', password: 'password').save()

        UserRole.create testUser, adminRole

        UserRole.withSession {
           it.flush()
           it.clear()
        }

        assert User.count() == 1
        assert Role.count() == 1
        assert UserRole.count() == 1
    } 
}
like image 54
erichelgeson Avatar answered May 04 '23 00:05

erichelgeson


You can also try the solution in https://github.com/grails/grails-core/issues/11376, where say that you can add to application.yml the config

hibernate:
    allow_update_outside_transaction: true
like image 35
Gelberth Amarillo Rojas Avatar answered May 04 '23 00:05

Gelberth Amarillo Rojas