0
votes

I have just read the basic information for the spring security core grails plugin and installed it in my grail project :

grails install-plugin spring-security-core

After that I have used s2-quickstart providing by the plugin :

grails s2-quickstart com.springsecurity SpringUser SpringRole

So basically it has created required Login and Logout controllers, domain controllers and some view/gsp files for me.

Now for testing purpose I need to test one of the controller, so I have created one sample controller which is named as Secure with following code :

package com.springsecurity;
import grails.plugins.springsecurity.Secured;

class SecureController {
    @Secured(['ROLE_ADMIN'])
    def index = {
        render 'Secure access only'
    }
}

Now from the documentation I have found one step where it's showing me to create a default user and it's role from Bootstrap.groovy. So I have write the following piece of code in Bootstrap.groovy :

def adminRole = new SpringRole(authority: 'ROLE_ADMIN').save(flush: false)
def userRole = new SpringRole(authority: 'ROLE_USER').save(flush: false)
String password = springSecurityService.encodePassword('password')
def testUser = new SpringUser(username: 'me', enabled: true, password: password)
testUser.save(flush: false)
SpringUserSpringRole.create testUser, adminRole, true
assert SpringUser.count() == 1
assert SpringRole.count() == 2
assert SpringUserSpringRole.count() == 1

One thing I would like to know here is that I have not created any table yet in the backend. So is it required at this step or the above code will store the single user in the session ?

With above piece of code I am getting following exception at the time of running the project :

2010-11-11 11:42:47,932 [main] ERROR context.GrailsContextLoader  - Error executing bootstraps: getFlushMode is not valid without active transaction
org.hibernate.HibernateException: getFlushMode is not valid without active transaction
        at $Proxy16.getFlushMode(Unknown Source)
        at BootStrap$_closure1.doCall(BootStrap.groovy:29)
        at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:251)
        at grails.util.Environment.executeForEnvironment(Environment.java:244)
        at grails.util.Environment.executeForCurrentEnvironment(Environment.java:220)
        at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:164)
        at grails.web.container.EmbeddableServer$start.call(Unknown Source)
        at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy:158)
        at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy)
        at _GrailsSettings_groovy$_run_closure10.doCall(_GrailsSettings_groovy:280)
        at _GrailsSettings_groovy$_run_closure10.call(_GrailsSettings_groovy)
        at _GrailsRun_groovy$_run_closure5.doCall(_GrailsRun_groovy:149)
        at _GrailsRun_groovy$_run_closure5.call(_GrailsRun_groovy)
        at _GrailsRun_groovy.runInline(_GrailsRun_groovy:116)
        at _GrailsRun_groovy.this$4$runInline(_GrailsRun_groovy)
        at _GrailsRun_groovy$_run_closure1.doCall(_GrailsRun_groovy:59)
        at RunApp$_run_closure1.doCall(RunApp.groovy:33)
        at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
        at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
        at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
        at gant.Gant.withBuildListeners(Gant.groovy:427)
        at gant.Gant.this$2$withBuildListeners(Gant.groovy)
        at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
        at gant.Gant.dispatch(Gant.groovy:415)
        at gant.Gant.this$2$dispatch(Gant.groovy)
        at gant.Gant.invokeMethod(Gant.groovy)
        at gant.Gant.executeTargets(Gant.groovy:590)
        at gant.Gant.executeTargets(Gant.groovy:589)
Application context shutting down...
Application context shutdown.

After seeing the above error, I am feeling that it's actually trying to store the specified object (in Bootstrap.groovy) to database and there is no table so it's throwing some exception.

Any help would be highly appreciated...

Thanks in advance..

3
1. You didn't mention it created SpringUser and SpringRole domain classes, but I suppose it's so. 2. Did you put that code into init{} method of BootStrap? Domain class operations should work in there. 3. You could try just removing flush: false, it won't harm functionality, will just add more DB roundtrips. 4. You can also try doing it in explicit transaction, like SpringRole.withTransaction{}Victor Sergienko

3 Answers

3
votes

The error message is "getFlushMode is not valid without active transaction" which doesn't have anything to do with whether there are tables or not.

If you're using dbCreate=create-drop or dbCreate=update in DataSource.groovy then all of the tables for your domain classes will be created for you. If you've disabled dbCreate then yes, you'll need to create the associated tables, but this is necessary any time you add one or more domain classes to a Grails app.

Looking at the Grails User mailing list it looks like this is a jar file conflict from something you added to your lib directory or something added by another plugin. One user found that Drools 4.0 was the problem when he saw this error. Do you have plugins that include Hibernate jars, or other libraries that Hibernate depends on, e.g. Antlr?

1
votes

Got it finally...

Just commented following line in hibernate.cfg.xml

<property name="current_session_context_class">thread</property>
0
votes

Not sure if you saw this but there is a pretty detailed walkthrough on how to do this here:

http://blog.springsource.com/2010/08/11/simplified-spring-security-with-grails/

Specifically it seems that your hibernate code is not contained within a hibernate session (which your test code probably is not setting up properly) and thus the error message. Typically you want to configure hibernate with hibernate.hbm2ddl.auto to have it auto-create tables and such.

For more information on hibernate.hbm2ddl.auto you can look here:

Hibernate hbm2ddl.auto possible values and what they do?

Grant