[memcached-session-manager] Session Failover with Groovy on Grails Applications

157 views
Skip to first unread message

Johannes

unread,
Apr 17, 2010, 1:05:16 PM4/17/10
to memcached-session-manager
Hi everyone,

this week I tried to use the memcached-session-manager for session
failover with a Grails App. It turned out that this works fine with
the JavaSerializationTranscoderFactory but caused a hibernate
exception with the Javolution one.

Following, I will try to explain what happened and it get's a bit
grails specific, but maybe someone else runs into the same situation
and can use the info. At the end of the mail you can find an excerpt
of catalina.out with the stacktrace of the exception.

First of I have a Person object inside the session that contains some
other attributes. Now for every attribute inside Person that was
defined within a hasMany relationship, the exception occurred when
trying to save the session to the memcached node. ( in Person: static
hasMany = [depotPositions: DepotPosition,...]). Setting the fetching
mode for the attribute to 'eager' did solve part of the problem
(in Person: static mapping = { ... columns { depotPositions lazy:
false ...} ...}
but the exception still occurred for attributes that had a hasMany
relationship defined within themselves.
Applying the same trick twice had then however no effect, meaning the
same exception still occured.
I hope this helps or is at least of some interest ;)

Cheers,
Johannes



----------------------------------------------
15.04.2010 08:00:20
de.javakaffee.web.msm.serializer.javolution.ReflectionFormat
writeElements
SCHWERWIEGEND: Could not write element for field.
org.hibernate.LazyInitializationException: failed to lazily initialize
a collection of role: Person.depotPositions, no session or session was
closed
at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:
380)
at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:
372)
at
org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:
119)
at org.hibernate.collection.PersistentSet.size(PersistentSet.java:
162)
at de.javakaffee.web.msm.serializer.javolution.ReflectionBinding
$XMLCollectionFormat.write(ReflectionBinding.java:381)
at de.javakaffee.web.msm.serializer.javolution.ReflectionBinding
$XMLCollectionFormat.write(ReflectionBinding.java:335)
at javolution.xml.XMLFormat$OutputElement.add(XMLFormat.java:819)
at
de.javakaffee.web.msm.serializer.javolution.ReflectionFormat.writeElements(ReflectionFormat.java:
262)
at
de.javakaffee.web.msm.serializer.javolution.ReflectionFormat.write(ReflectionFormat.java:
244)
at javolution.xml.XMLFormat$OutputElement.add(XMLFormat.java:819)
at de.javakaffee.web.msm.serializer.javolution.ReflectionBinding
$XMLMapFormat.write(ReflectionBinding.java:439)
at de.javakaffee.web.msm.serializer.javolution.ReflectionBinding
$XMLMapFormat.write(ReflectionBinding.java:389)
at javolution.xml.XMLFormat$OutputElement.add(XMLFormat.java:819)
at javolution.xml.XMLObjectWriter.write(XMLObjectWriter.java:242)
at
de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoder.doSerialize(JavolutionTranscoder.java:
125)
at
de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoder.serializeAttributes(JavolutionTranscoder.java:
97)
at
de.javakaffee.web.msm.TranscoderService.serializeAttributes(TranscoderService.java:
140)
at
de.javakaffee.web.msm.BackupSessionTask.serializeAttributes(BackupSessionTask.java:
150)
at
de.javakaffee.web.msm.BackupSessionTask.call(BackupSessionTask.java:
101)
at
de.javakaffee.web.msm.BackupSessionTask.call(BackupSessionTask.java:
38)
at de.javakaffee.web.msm.BackupSessionService
$SynchronousExecutorService.submit(BackupSessionService.java:324)
at
de.javakaffee.web.msm.BackupSessionService.backupSession(BackupSessionService.java:
195)
at
de.javakaffee.web.msm.MemcachedBackupSessionManager.backupSession(MemcachedBackupSessionManager.java:
670)
at
de.javakaffee.web.msm.SessionTrackerValve.backupSession(SessionTrackerValve.java:
157)
at
de.javakaffee.web.msm.SessionTrackerValve.invoke(SessionTrackerValve.java:
92)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:
558)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
127)
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:
298)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:
852)
at org.apache.coyote.http11.Http11Protocol
$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:
489)
at java.lang.Thread.run(Thread.java:619)


--
Subscription settings: http://groups.google.com/group/memcached-session-manager/subscribe?hl=en

Martin Grotzke

unread,
Apr 19, 2010, 2:50:52 AM4/19/10
to memcached-se...@googlegroups.com
Hi Johannes,

thanx for reporting this! I think the problem here is that when
ReflectionBinding.XMLCollectionFormat wants to determine the
collection size, the hibernate session is already closed.

One solution I have in mind is that PersistentSet (or
AbstractPersistentCollection more general) are not handled by the
XMLCollectionFormat which uses the public api of collection, but that
those collections are handled by the ReflectionFormat (you can imagine
what it does :-)). So public api would not be used but just the
internal state would be serialized/deserialized.

For this we'd need an additional attribute like
"forceReflectionConverter" that would take a comma separated list of
class names.

What do you think about this?

Of course this solution needs to be verified :-)

Cheers,
Martin
--
Martin Grotzke
http://www.javakaffee.de/blog/
Reply all
Reply to author
Forward
0 new messages