In general, however, you are advsied not to store mutable objects into
the session.  The mechanism used to persist into the session should be
opaque to the programmer, and it is likely that a persistence
mechanism will only actually store an object if it has changed since
the last time it was stored.  Admittedly, this will work just fine if
you are running on a single host, but it isn't guaranteed to do so.
As soon as you start distributing your sessions around a cluster,
however, you will run into real difficulties, because changes to the
session are only replicated if the reference to a persistent entity
has changed.  Since your reference is to a mutable object, it is
possible to modify the object (by adding or removing a key or value)
without modifying the reference to it.  This would cause the map to
fail to be propagated to the cluster.

For session distribution, there is a nice fix for this problem you can
use.  There is an interface you can implement (the name of which
escapes me) which will allow the session to ask the object whether it
needs to be distributed.  But there is also a base class you can
extend called org.apache.tapestry.BaseSessionStoreOptimized.  If you
look at the javadoc for that object, you'll see the interface name I
was speaking of. BaseSessionStoreOptimized provides a method you can
call whenever you modify your mutable object which will cause the
object to correctly notify the session manager that it needs to be
redistributed.

Now, I have absolutely no idea if the @Persist annotation is smart
enough to check for the existence of the interface in question and
test for modifications as appropriate, but it might be.  But at least
you now know why you should avoid mutable objects in the session.
Maybe the tap devs can fix the annotation if it doesn't already do
this.

--sam


On 12/7/06, Dan Adams <[EMAIL PROTECTED]> wrote:
So I added an @InitialValue which calls a method to create the initial
map and this seems to have fixed it. After reading the enhancement
source I found out something tricky about this.

SpecifiedPropertyWorker.addReinitializer gets called if you don't set an
initial value and it basically does (for property 'foo'):

in finishLoad():
foo$default = foo;

in pageDetached():
foo = foo$default;

now, in my class in finishLoad I was doing essentially:
foo = new HashMap();

So on the first call to the page this would set the default value of the
property to that specific object. So if you reset your session you would
get the same object back when it initialized it to the default value.

However, when you use @InitialValue the enhancement adds the following:

finishLoad():
foo$initialValueBinding = foo$initialValueBinding.createBinding(this);
foo = (evaluate the binding);

pageDetached():
foo = (evaluate the binding);

So it appears that if you are going to @Persist an object and need the
initial value to not be null you should be sure to use @InitialValue or
otherwise you could end up with some weirdness. In my case it works if
you test it naively but fortunately my test cases were robust enough to
catch it.

On Thu, 2006-12-07 at 10:58 -0500, Dan Adams wrote:
> I need a sanity check. :) So I have the following map of maps which I
> need to persist in the user session:
>
> @Persist
> public abstract Map<String, Map<String, Object>> getPageParameters();
> public abstract void setPageParameters(Map<String, Map<String, Object>>
> params);
>
> Everything seems to work fine except that if I clear my session by
> deleting my cookies and come back to the page getPageParameters()
> returns the same map rather than null. I mean, it should return null
> right? I'm running this in Jetty in case it matters.
>
--
Dan Adams
Senior Software Engineer
Interactive Factory
617.235.5857


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to