Access session scoped bean from request scoped bean

jsf, jsf-2, session-scope

Solution

Instead of creating a new `UserModel` instance in your `UserController`, inject it with `@ManagedProperty`.

In `UserController`:

@ManagedProperty(value="#{userModel}")
private UserModel model;

// add getter and setter for userModel (important!)

Then you don't have to instantiate it in the constructor and will always get the session scoped instance of `UserModel` in your controller.

UPDATE:

I think you are complicating the login process with your strict MVC approach. In JSF the borderlines between model, view and controller are somewhat blurred or overlapping.

I recommend reading this interesting question and answers and especially this answer for more information on that topic.

As to your concrete problem. I am not quite sure what is the reason but what you should definitely avoid is to instantiate managed bean by youself and fiddle around with both injected and self-initialized instances of beans.

Also I would recommend to merge your beans together into a single bean. Then you don't have the problems with circular dependencies and null references.

Problem

I'm trying to use a pattern found on a IceFaces page.(I'm not using IceFaces, using PrimeFaces) In this case I have two beans: UserController and Usermodel On my UserModel I have a instance of UserVO (created by another programmer). On My UserController I have this: ``` @ManagedBean @RequestScoped public class UserController implements Serializable { private static final long serialVersionUID = 1L; private UserBO bo; private UserModel model; public UserController() { bo = new UserBO(); model = new UserModel(); } public void Login() throws IOException { model.setUserVo(bo.executeLogin(model.getUserVo())); ExternalContext externalContent = FacesContext.getCurrentInstance().getExternalContext(); if (!model.getUserVo().isError()) { model.setLoggedIn(true); externalContent.getSessionMap().put("userSession", model); externalContent.redirect(externalContent.getRequestContextPath() + "/views/request/search.html"); } else { model.setLoggedIn(false); FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, model.getUserVo().getMessage(), model.getUserVo().getLogin()); FacesContext.getCurrentInstance().addMessage(null, facesMessage); } } public UserBO getBo() { return bo; } public void setBo(UserBO bo) { this.bo = bo; } public UserModel getModel() { return model; } public void setModel(UserModel model) { this.model = model; } } ``` As you can see, I create a new instance of UserModel and set it with what was returned from the `bo.executeLogin()` and it is working, my object is returned. To make sure the user is logged in, I have a property on my UserModel: ``` @ManagedBean @SessionScoped public class UserModel { private UserVO userVo; private Boolean loggedIn = false; public UserModel() { userVo = new UserVO(); } public UserVO getUserVo() { return userVo; } public void setUserVo(UserVO userVo) { this.userVo = userVo; } public Boolean getLoggedIn() { return loggedIn; } public void setLoggedIn(Boolean loggedIn) { this.loggedIn = loggedIn; } ``` I have a template.xhtml with: ``` <ui:fragment rendered="#{userModel.loggedIn}"> <ui:include src="../includes/top.xhtml"/> </ui:fragment> ``` And the thing is that it is not working, is not getting the `loggedIn` property value. My guess is that accessing this way I'm kinda creating a new instance of UserModel, if so, it is a problem because my UserController is not session scoped, only the UserModel EDIT Instead of using this `loggedIn` property I know I can simply check if the UserModel `userVo` property is set but the problem is about the session scoped bean, I can't access it from UserController, where it is set because it isn't scoped session, and my template.xhtml will be used by every page.

Original source

Related problems