Quantcast

Accessing hibernate from HttpSessionListener

classic Classic list List threaded Threaded
6 messages Options
pgf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Accessing hibernate from HttpSessionListener

pgf
I know this topic has come up a number of times but I have been unable to get anything working in my HttpSessionListener.sessionDestroyed() method. When the http session times out I need to delete a User instance from the database. The sessionDestroyed() method is called asynchronously so grailsApplication is null. How can I make this work?

package com.ibm.gnm

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * 
 * Custom HttpSessionListener that logs out a user when the session times out.
 * This deletes all the objects owned by that user and prevents crud from
 * piling up in the database.
 *
 */
public class CustomHttpSessionListenerService implements HttpSessionListener {

	private CustomHttpSessionListenerService customHttpSessionListenerService;

	def grailsApplication
	def user
	
	/**
	 * Called when a new HttpSession is created
	 * 
	 * @param event HttpSessionEvent object
	 */
	public void sessionCreated(HttpSessionEvent event) {
		String id = event.getSession().getId();
		log.info "Session ${id} created"
	}

	/**
	 * Called when a HttpSession is destroyed (eg. on timeout). Deletes the
	 * User object associated with the session to clean up the user's
	 * temporary data.
	 * 
	 * @param event HttpSessionEvent object
	 */
	public void sessionDestroyed(HttpSessionEvent event) {
		
		String id = event.getSession().getId()
		def user = userClass.findBySessionId( id )
		if ( user ) {
			log.info "Session ${id} destroyed - automatically logging out user ${user.getUserName()}"
			user.delete()
			if (user.hasErrors()) {
				log.warn "Errors while cleaning up session ${id}:"
				user.errors().each() {
					log.warn it
				}
			}
		} else {
			log.info "Session ${id} destroyed - no user attached"
		}

	}

	/**
	 * Set the customHttpSessionListenerService property to this object.
	 * 
	 * @param customHttpSessionListenerService this object
	 */
	public void setMyListener(CustomHttpSessionListenerService customHttpSessionListenerService) {
		this.customHttpSessionListenerService = customHttpSessionListenerService
	}

	/**
	 * Returns the current custom listener.
	 * 
	 * @return value of the customHttpSessionListenerService property.
	 */
	private synchronized CustomHttpSessionListenerService getMyListener() {
		if (customHttpSessionListenerService == null) {
			customHttpSessionListenerService = (CustomHttpSessionListenerService)ApplicationHolder.getApplication().getMainContext().getBean("customHttpSessionListenerService")
		}
		return customHttpSessionListenerService
	}
}

Regards,

Peter Farr
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Accessing hibernate from HttpSessionListener

burtbeckwith
Why do you need the grailsApplication?

Burt

On Friday, January 13, 2012 07:06:46 AM pgf wrote:

> I know this topic has come up a number of times but I have been unable to get
> anything working in my HttpSessionListener.sessionDestroyed() method. When
> the http session times out I need to delete a User instance from the
> database. The sessionDestroyed() method is called asynchronously so
> grailsApplication is null. How can I make this work?
>
>
>
> -----
>
> Regards,
>
> Peter Farr
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Accessing-hibernate-from-HttpSessionListener-tp4292399p4292399.html


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


pgf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Accessing hibernate from HttpSessionListener

pgf
burtbeckwith wrote
Why do you need the grailsApplication?
Perhaps I don't. What I need is access to the User domain objects and any of their children.

Regards,

Peter Farr
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Accessing hibernate from HttpSessionListener

burtbeckwith
The listener class is written in Java? If so you can rewrite in Groovy, or call a Groovy helper class that can call GORM methods. If you're using 2.0 note that the non-dynamic GORM methods (get(), delete(), list(), findWhere(), etc.) are added via ASTs now so they're in the bytecode and callable from Java. Dynamic methods like findAllByNameAndAge aren't - those have to be handled with runtime metaprogramming.

Burt

On Friday, January 13, 2012 07:25:34 AM pgf wrote:

>
> burtbeckwith wrote
> >
> > Why do you need the grailsApplication?
> >
>
> Perhaps I don't. What I need is access to the User domain objects and any of
> their children.
>
> -----
>
> Regards,
>
> Peter Farr
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Accessing-hibernate-from-HttpSessionListener-tp4292399p4292456.html


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


pgf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Accessing hibernate from HttpSessionListener [SOLVED]

pgf
In reply to this post by pgf
Well, it seems that the answer is simple. All I had to do was add an @transactional notation to the sessionDestroyed() method, which also required importing org.springframework.transaction.annotation.Transactional. I thought the default for services was transactional, but apparently this is not true when called the way I am doing.

Regards,

Peter Farr
pgf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Accessing hibernate from HttpSessionListener

pgf
It seems I posted too soon. This only works if the User object does not have any other domain objects that belong to it. If any belongsTo class instances are involved (i.e. cascading deletes) then I get the following exception:

2012-01-13 10:45:45,484 events.PatchedDefaultFlushEventListener.error Could not synchronize database state with session
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
	at org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener.onApplicationEvent(AbstractPersistenceEventListener.java:46)
	at com.ibm.gnm.CustomHttpSessionListenerService.sessionDestroyed(CustomHttpSessionListenerService.groovy:51)
	at java.lang.Thread.run(Thread.java:662)
2012-01-13 10:45:45,546 [localhost].[/GNMWebTools].expire Session event listener threw exception
org.springframework.orm.hibernate3.HibernateSystemException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
	at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:683)
	at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
	at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
	at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
	at sun.reflect.GeneratedMethodAccessor426.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
	at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:189)
	at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi.delete(HibernateGormEnhancer.groovy:902)
	at com.ibm.gnm.User.delete(User.groovy)
	at com.ibm.gnm.User$delete.call(Unknown Source)
	at com.ibm.gnm.CustomHttpSessionListenerService.sessionDestroyed(CustomHttpSessionListenerService.groovy:51)
	at org.apache.catalina.session.StandardSession.expire(StandardSession.java:817)
	at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:668)
	at org.apache.catalina.session.ManagerBase.processExpires(ManagerBase.java:533)
	at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:518)
	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1212)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1391)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1401)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1380)
	at java.lang.Thread.run(Thread.java:662)
Caused by: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
	at org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener.onApplicationEvent(AbstractPersistenceEventListener.java:46)
	at com.ibm.gnm.CustomHttpSessionListenerService.sessionDestroyed(CustomHttpSessionListenerService.groovy:51)

Regards,

Peter Farr
Loading...