0

I have some variables in JSF managedbean with different scopes (that I feel). In the following snippet, userTable is used in both login() and register() method. But roleList is used only in register() method.

userTable should be in session scope, since it should be accessable during user session.

And I feel like roleList should not be in session scope, since it will be populated in a combo box during registration page only. I guess request scope is enough.

But how can I put roleList in requestScope since UserManagedBean is in session scope already.

Thanks much for any advice.

@Named("user")
@Scope("session")
public class UserManagedBean implements Serializable {

    private UserTable userTable = new UserTable(); 
    private List roleList = new ArrayList();

    public String login() {
     // login process here
    }

    public String register() {
     // register user here
    }
Sasue Nie
  • 61
  • 1
  • 9
  • why don't you create another managed bean of request scope, and use it in registration page ? I think, user will use registration page once for registration – Laabidi Raissi Mar 26 '13 at 13:57
  • Are you sure you really need to inject another managed bean in this one or you're thinking about `UserTable` as your business logic class? – Luiggi Mendoza Mar 26 '13 at 14:04
  • I am thinking about it too. But what if there are two variables with different scopes in one method (e.g in register())? – Sasue Nie Mar 26 '13 at 14:07
  • @Luiggi Mendoza UserTable is just a POJO, no business logic. – Sasue Nie Mar 26 '13 at 14:09
  • Then don't worry about it. You don't have a managed bean inside another. Refer to [Difference between managed bean and backing bean](http://stackoverflow.com/a/4713564/1065197) to understand what is a managed bean. – Luiggi Mendoza Mar 26 '13 at 14:12
  • @Luiggi Mendoza I don't get you. Sorry I am very new to JSF. In servlet, we can put any variable in any scope. Now in managed bean, I am thinking I cannot define the scope of variable individually. – Sasue Nie Mar 26 '13 at 14:25
  • Please go through a JSF tutorial that explains from the basic concepts since you have lot of misconceptions. There are good tutorial links on [StackOverflow JSF wiki](http://stackoverflow.com/tags/jsf/info). – Luiggi Mendoza Mar 26 '13 at 14:37
  • yes I think you should follow Luiggi advice – Laabidi Raissi Mar 26 '13 at 14:43

1 Answers1

1

As to the concrete question, just split the bean in 2 separate beans. As you're apparently managing beans by Spring instead of by JSF or CDI for some unclear reason, you can use @Autowired to inject the one bean as a property of the other bean.

@Named
@Scope("request")
public class Login implements Serializable {

    private List<Role> roles;

    @AutoWired
    private User user;

    public String submit() {
         UserTable userTable = user.getTable();
         // ...
    }

    // ...
}
@Named
@Scope("session")
public class User implements Serializable {

    private UserTable table;

    // ...
}

If you were managing the beans by JSF @ManagedBean, you could use @ManagedProperty for that. If you were managing the beans by CDI @Named, you could use @Inject for that.


Coming back to the concrete functional requirement,

And I feel like roleList should not be in session scope, since it will be populated in a combo box during registration page only. I guess request scope is enough.

That's a pretty weak reason. If it were me, I'd have placed it in the application scope. The role list is the same for every single request/session anyway, right? You don't need to reload/repopulate it on every request then, unless you've a really, really low memory footprint.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • That is a very good answer. So I should split the beans. Is it possible to have instance variables with different scope in a single ManagedBean? I used to think that login, register, logout functions are related to User, thats why I should put all these functions in a single UserManagedBean. Is there any good practices to split the functions and managed beans? Absolutely roleList should be in application scope for my case. Thanks much. – Sasue Nie Mar 26 '13 at 15:51
  • That's tight coupling. For starters, use a separate request/view scoped bean per ``. It'll automagically end up in clean code. Note that I've updated my answer with a link "How to choose the right bean scope?", I recommend to give it a read. – BalusC Mar 26 '13 at 15:54
  • I read somewhere that by using JSR330 in Spring, I could reuse that managedbean in another CDI environment. Thats why I am mixing Spring with JSR330. Do you have any comment on that? – Sasue Nie Mar 26 '13 at 15:57
  • Sorry, I don't use Spring anyway. Just the standard Java EE stack. I just use EJB instead of Spring services and CDI instead of Spring DI and `@Interceptor` instead of Spring AOP. Spring was nice during the J2EE ages when EJB was terrible and CDI didn't exist. Java EE 5/6 learnt and incorporated a lot of lessons of Spring which makes Spring superfluous. Even more, Spring is considered "legacy" nowadays. It even ends up in more XML boilerplate than Java EE. – BalusC Mar 26 '13 at 16:01