-
1. Re: Removing or replacing a contextual bean
nickarls May 1, 2009 8:37 PM (in response to dan.j.allen)The remove would be handy, yes. In Seam I sometimes just clear the instance from the context to get a fresh instance from a factory.
Explicit set would be handy for outjection-like stuff but it was probably considered a no-no to have session scoped beans end up in application and request scopes.
The spec mentions
This restriction allows the container to use a client proxy
regarding the null producer methods products... -
2. Re: Removing or replacing a contextual bean
dan.j.allen May 2, 2009 7:32 AM (in response to dan.j.allen)I just can't seem to wrap my head around this. I figured out one way to remove a bean (as opposed to a producer method result):
Set<Bean<User>> candidates = manager.resolveByType(HotelSearch.class); assert candidates.size() == 1; candidates.iterator().next().destroy(manager.getInstanceByType(HotelSearch.class));
However, that is just downright ugly and I don't even think it is allowed.
Now producer methods can have a corresponding dispose method, which would be called by destroy if the type is the result of a @Producer method. The problem there is that the dispose method just receives the instance it is disposing...so you can act on it (such as close a connection if it's an EntityManager) but you can remove it from the context.
So I'm having a tremendously difficult time with sticky state.
-
3. Re: Removing or replacing a contextual bean
nickarls May 3, 2009 10:12 PM (in response to dan.j.allen)Just add a remove method in AbstractMapContext, noone will notice ;-)
-
4. Re: Removing or replacing a contextual bean
gonorrhea May 5, 2009 10:46 PM (in response to dan.j.allen)
Dan Allen wrote on May 02, 2009 07:32:
So I'm having a tremendously difficult time with sticky state.That sounds foreboding, coming from the SiA author...
Sounds like something potentially simple/basic was overlooked in the spec/RI???
-
5. Re: Removing or replacing a contextual bean
dan.j.allen May 5, 2009 11:21 PM (in response to dan.j.allen)I won't say that. Likely just me just being think-headed. I like to say that may head holds stuff in good, but sometimes it takes a while for it to seep through the membrane ;)
-
6. Re: Removing or replacing a contextual bean
nickarls May 6, 2009 9:07 AM (in response to dan.j.allen)I don't think the spec actually forbids removing stuff from context.
And even if it would, it's not final yet ;-)
-
7. Re: Removing or replacing a contextual bean
dan.j.allen May 8, 2009 9:57 PM (in response to dan.j.allen)I'm pretty sure that the spec is discouraging the explicit removal of a bean from the contexts. I'm personally having a hard time with this. I really don't see what the problem is. Once you remove it, then the next time you request it, the bean is simply resolved/instantiated again.
-
8. Re: Removing or replacing a contextual bean
dan.j.allen May 8, 2009 10:12 PM (in response to dan.j.allen)So what I am saying is that there is a distinct difference between destroy and remove. Destroy let's you terminate the state of a bean. Remove gets it out of the context to make room for a new instance to move in.
-
9. Re: Removing or replacing a contextual bean
dan.j.allen May 8, 2009 10:35 PM (in response to dan.j.allen)I want to emphasize that where this becomes a problem is on a JSF postback. Let's say you produce a value into the request scope. If JSF happens to retrieve the value while walking the tree before the Invoke Application phase, and your action changes the value that backs the producer, then when you render, you see the old value rather than the new value (a stale value). This was a case in Seam where outjection proved useful because it could
update
the variable with the new value. Not that we need outjection, but just so you understand what it was doing in this case. There is something more fine-grained than request scope.If I introduce the Web Beans API, I can achieve this functionality using the following call:
Context requestContext = manager.getContext(RequestScoped.class); ((AbstractThreadLocalMapContext) requestContext).getBeanStore().remove(manager.resolveByName("results").iterator().next());
-
10. Re: Removing or replacing a contextual bean
nickarls May 8, 2009 10:58 PM (in response to dan.j.allen)Actually, BeanStore.remove() isn't really used anywhere and should, as such, be removed ;-)
-
11. Re: Removing or replacing a contextual bean
gavin.king May 12, 2009 9:28 AM (in response to dan.j.allen)If you want to remove something from a context before the context ends, then the scope you defined was obviously incorrect :-)
Make it an attribute of an object, not a first-level contextal object.
-
12. Re: Removing or replacing a contextual bean
dan.j.allen May 15, 2009 6:44 PM (in response to dan.j.allen)You are making these scopes like Hotel California. I don't agree that just because I want to remove an object from a context that I have chosen the wrong scope. Then longer term scopes, especially, can grow without bounds. There are plenty of cases when you need to get an object out of a scope without killing the whole scope. And it greatly hinders the feasibility of using first-level context objects, which was a pattern Seam really espoused.
I want to emphasize two cases here so that we have an architectural problem to discuss.
As you know, JSF walks the hell out of the tree on a postback, enough that it's very likely it is going to resolve your bean before the Invoke Application phase. Now, if that bean is created by a request-scoped producer, then you are stuck with that value until the page finishes rendering, even if the intent of the action was to change that value. Let's say the current user is managed by a session-scoped bean, but assigned as a first-level context object by a request-scoped producer. At first, you are a guest. Then you login. Now even request scope is
the incorrect scope
. The alternative is a dependent-scoped producer, but then the method gets abused by JSF. You could also do #{currentUser.user} but we've been spoiled into just having #{currentUser}. I just want to stick currentUser in the session and clear it when I want a different one in the session.Another case is a conversation-scoped search. The results are produced into conversation-scope. To update them, you have to clear the list and use addAll() to repopulate the result list. That seems like a workaround to me for not being about to clear and output a new result list.
Frankly, if you can't remove values from contexts, I anticipate that people are going to fear using these contexts because of their
stickiness
and go with a more stateless approach. -
13. Re: Removing or replacing a contextual bean
dan.j.allen May 15, 2009 7:06 PM (in response to dan.j.allen)As I try to play Devil's advocate on myself, I guess the answer is that you always use manager components...and the manager components can dump their state and reestablish as needed. Then, you never produce anything into a long-term scope...otherwise it is out there in the open unmanaged and no way to clear it. I just happen to not like the idea of having to bid farewell to that approach.
-
14. Re: Removing or replacing a contextual bean
gonorrhea May 15, 2009 8:51 PM (in response to dan.j.allen)Along the same lines, what about
promoting
ordemoting
context variables into different scopes (e.g. conversation-scoped variable promoted to session-scope, etc.)?I'm not sure that's currently possible with Seam 2.x...