I'll start by saying true, on some level that does work. And it's reasonable.

However, it challenges one of the core principles in Seam. You can argue whether that matters, but let's just follow this point. Seam focused on avoiding where possible the use of getter methods to access data. Instead, data was "pushed out" into top-level context variables where they could be accessed without an intermediary. The reason this was done is to avoid repeated invocation of getter methods. It's specially a solution that targets JSF since JSF bombards getter methods during the life cycle processing. Presuming that each method call is intercepted, there is a moderate to severe performance hit as a result.

Looking at your case, you have reduced the number of calls to once per request. That's alleviates the performance problem and allows the user to be an independent variable for at least the scope of the request. However, it behaves very badly with a JSF postback. Why? When the request begins, JSF produces the user, which prior to login is some transient/blank User object. During the postback, the user logs in, effectively updating the User object to a managed entity. But what remains in the request scope is the transient/blank User object. What you need is for the producer to reproduce at that point.

One way around the dilemma I just cited is to redirect before render, so as to break your association with the current request scope and have the user produced again on the next request. However, it seems pretty ugly to me to have to redirect just to clear the result of a request-scoped producer method you need to reset.

Would it be possible to have the producer method observe and event that would force it to produce again? That would solve most of the cases....and certainly it would solve this case.

If that isn't possible, you have to change the scope of @Produces @LoggedIn getCurrentUser() to @Dependent, which is nothing more than an alias for the getter method...the point I started with.

-Dan

On Thu, May 7, 2009 at 7:18 AM, Pete Muir <pmuir@redhat.com> wrote:
This is something that was quite commonly needed in Seam, in part due to the use of outjection. As 299 doesn't support outjection, you need to use the manager pattern:

@SessionScoped
public class Login {

  public User user;

  public Login(@New User user) {
     // Initialize with an empty, new, user - the "not logged in" user
     this.user = user;
  }

  public void login(User user) {
     // Log in a real user
     this.user = user;
  }

  @Produces @LoggedIn @RequestScoped
  public User getCurrentUser() {
     return user;
  }

}

This is much cleaner :-)


--
Pete Muir
http://www.seamframework.org
http://in.relation.to/Bloggers/Pete

_______________________________________________
seam-dev mailing list
seam-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/seam-dev



--
Dan Allen
Senior Software Engineer, Red Hat | Author of Seam in Action

http://mojavelinux.com
http://mojavelinux.com/seaminaction
http://in.relation.to/Bloggers/Dan

NOTE: While I make a strong effort to keep up with my email on a daily
basis, personal or other work matters can sometimes keep me away
from my email. If you contact me, but don't hear back for more than a week,
it is very likely that I am excessively backlogged or the message was
caught in the spam filters.  Please don't hesitate to resend a message if
you feel that it did not reach my attention.