LazyInitialization Exceptions with Webflow 1.3.4 and Shiro 1.1-SNAPSHOT
Hi Guys
Trying to perform a simple web flow.
here is the class
Code:
class RegistrationController {
static allowedMethods = [save: "POST", update: "POST", delete: "POST", register: "POST", register: "GET"]
def index = {
redirect(action:"register")
}//end index screen
//renders the menu of the page - or the landing page for this controller
def menu = {
chain(action:register,model: [personInstance: new Person()])
}//end show registration menu
// a web flow for registering a new student
def registerFlow = {
createStudent {
//if create button is clicked
log.debug('Entering createStudent')
on("create")
{
log.debug('inside on create')
def personInstance = new Person(params)
if (!personInstance.validate()) {
flow.student = personInstance
}
else
{
flash.message = "${message(code: 'minimalist.created.message', args: [RegistrationSchedule])}"
flow.student = personInstance
return error()
}
}.to "registerStudent"
//if cancel button is clicked
on("cancel")
{
log.debug('inside on cancel')
redirect( action:"menu")
}
}//create student
registerStudent{
on("register")
{
def registrationInstance = new RegistrationSchedule(params)
if (!registrationInstance.validate()) {
flow.registration = registrationInstance
flow.student.schedules.add(registration)
}
else
{
flash.message = "${message(code: 'minimalist.created.message', args: [RegistrationSchedule])}"
flow.registration = registrationInstance
return error()
}
}
.to "verifyRegistration"
//if back button is clicked
on("back").to "create"
//if cancel button is clicked
on("cancel")
{
redirect( action:"menu")
}
}//register student
verifyRegistration{
on("finish").to "showMenu"
//if back button is clicked
on("back").to "create"
on("cancel")
{
redirect( action:"menu")
}
}//print registration
showMenu {
redirect( action:"menu")
}
}//registration flow
}
and I get this exception when I attempt to go to the first node on the flow:
Code:
2010-08-16 14:17:17,379 [http-8080-2] ERROR errors.GrailsExceptionResolver - failed to lazily initialize a collection of role: ShiroUser.permissions, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ShiroUser.permissions, no session or session was closed
at ShiroDbRealm.isPermitted(ShiroDbRealm.groovy:76)
at ShiroDbRealm$isPermitted.call(Unknown Source)
at org.apache.shiro.grails.RealmWrapper.isPermitted(RealmWrapper.groovy:227)
at org.apache.shiro.grails.RealmAdapter.isPermitted(RealmAdapter.java:57)
at org.apache.shiro.authz.ModularRealmAuthorizer.isPermitted(ModularRealmAuthorizer.java:224)
at org.apache.shiro.mgt.AuthorizingSecurityManager.isPermitted(AuthorizingSecurityManager.java:114)
at $Proxy9.isPermitted(Unknown Source)
at org.apache.shiro.subject.support.DelegatingSubject.isPermitted(DelegatingSubject.java:153)
at ShiroGrailsPlugin.accessControlMethod(ShiroGrailsPlugin.groovy:505)
at ShiroGrailsPlugin.accessControlMethod(ShiroGrailsPlugin.groovy)
at ShiroGrailsPlugin$_closure3_closure23.doCall(ShiroGrailsPlugin.groovy:250)
at SecurityFilters$_closure1_closure2_closure3.doCall(SecurityFilters.groovy:13)
at SecurityFilters$_closure1_closure2_closure3.doCall(SecurityFilters.groovy)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:275)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:343)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:272)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)
at org.apache.shiro.grails.SavedRequestFilter.doFilter(SavedRequestFilter.java:55)
at java.lang.Thread.run(Thread.java:619)
2010-08-16 14:17:17,398 [http-8080-2] ERROR [Tomcat].[localhost] - Exception Processing ErrorPage[errorCode=500, location=/grails-errorhandler]
java.lang.IllegalStateException: Cannot reset buffer after response has been committed
at org.apache.catalina.connector.Response.resetBuffer(Response.java:691)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:409)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:343)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:287)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
There isn't much out there about this exception but it appears to be something that Webflow had a while ago. Has anyone else seen this ? I am on grails 1.3.3 and a little desperate.
thanks
More clarification please
Apologies but I'm still a relative newbie to Grails / Groovy - doesn't help that somehow my STS doesn't really do any proper syntax highlighting. I've also encountered this problem in my usage of web flows but need a bit more clarification w.r.t. what @pledbrook mentioned. When you say you wrap the entire method in:
Code:
def isPermitted(...) {
ShiroUser.withTransaction {
...
}
}
I'm assuming you mean that if I had my web flow as such:
Code:
def createRuleFlow =
{
setProperties
{
...
}
}
then I should do the wrapping like:
Code:
def isPermitted(...) {
ShiroUser.withTransaction {
def createRuleFlow =
{
setProperties
{
...
}
}
}
}
But after doing that, I can't seem to access the flow any more. Does the access URL to my flow change after I do the wrapping?
Thanks!
Solved! I should have RTFM!!!
OK never mind - I did a closer look at the FAQ for Shiro and found that in the FAQ, this was mentioned:
Q: I get a LazyInitializationException when using the Shiro plugin with WebFlow. How do I fix it?
A: WebFlow actions bypass the standard GrailsOpenSessionInViewInterceptor which means that if you access the database from within a Grails filter, you won't have a Hibernate session available. This is what happens when you use the accessControl {} syntax from a filter.
Probably the best solution is to execute the database access from within a transaction, either by using withTransaction inside your realm methods, or modifying the realm to delegate to a transactional service.
I then realized the "wrapping" should be done within the conf/ShiroSecurityFilters.groovy around the "accessControl()" call. I did that and finally this was resolved.