title: JSF: Attribute of session scoped managed bean becomes null
body: <p>I am playing with JavaEE 7 and tried to write a webapp with a simple login mechanism.</p>
  
  <p>There is an EJB entity class persisted with JPA called <code>User</code> holding data about users. In the WAR, a session scoped managed bean called <code>UserManagedBean</code> is responsible for tracking the current user, thus it has a property of type <code>User</code> that is set when someone logs in successfully. A filter is watching the value of this property and redirects to login page if necessary. Of course, both <code>User</code> and <code>UserManagedBean</code> are serializable (implementing the interface and not containing anything non-serializable).</p>
  
  <p>My problem is that after the <em>successful</em> login, refreshing the page throws me back to the login page AND my previously set <code>user</code> property is now null (actually this is why the filter triggers the redirect).</p>
  
  <p>Here is what I tried:</p>
  
  <ul>
  <li>Separated logic and data: UserManagedBean now only has this one property and a few helper methods, no EJBs, nothing related to Java magic.</li>
  <li>Tried setting the <code>javax.faces.STATE_SAVING_METHOD</code> context parameter in the web.xml to both server and client, nothing changed.</li>
  <li>Verified that the session scoped managed bean remains the same: only one of it is created, but somehow the value of user is nulled after navigating from the login page.</li>
  <li>According to the NetBeans debugger, the <code>user</code> field is not accessed apart from setting it to the logged in user.</li>
  <li>Specifying custom serialization methods revealed that UserManagedBean is not serialized or deserialized during the experiment.</li>
  <li>Debugging in Chrome suggests that the session ID is saved in the cookie and is not changed when the value of <code>user</code> is lost.</li>
  <li>No exceptions are detected.</li>
  </ul>
  
  <p>I must be missing something trivial, any help would be appreciated.</p>
  
  <p>(<strong>UPDATE:</strong> It was indeed trivial and <em>not related to JSF or managed beans</em>, see my answer below.)</p>
  
  <p>My code is the following:</p>
  
  <p><code>User</code> class:</p>
  
  <pre><code>@Entity(name = "USERS")
  public class User implements Serializable {
      private static final long serialVersionUID = 1L;
      @Id
      private String username;
      private boolean administrator;
      private byte[] salt;
      private byte[] passwordHash;
  
      public String getUsername() {
          return username;
      }
  
      public void setUsername(String userName) {
          this.username = userName;
      }
  
      public boolean isAdministrator() {
          return administrator;
      }
  
      public void setAdministrator(boolean administrator) {
          this.administrator = administrator;
      }
  
      public byte[] getSalt() {
          return salt;
      }
  
      public void setSalt(byte[] salt) {
          this.salt = salt;
      }
  
      public byte[] getPasswordHash() {
          return passwordHash;
      }
  
      public void setPasswordHash(byte[] passwordHash) {
          this.passwordHash = passwordHash;
      }
  
      @Override
      public int hashCode() {
          int hash = 0;
          hash += (username != null ? username.hashCode() : 0);
          return hash;
      }
  
      @Override
      public boolean equals(Object object) {
          // TODO: Warning - this method won't work in the case the id fields are not set
          if (!(object instanceof User)) {
              return false;
          }
          User other = (User) object;
          if ((this.username == null &amp;&amp; other.username != null) || (this.username != null &amp;&amp; !this.username.equals(other.username))) {
              return false;
          }
          return true;
      }
  
      @Override
      public String toString() {
          return "hu.bme.aut.mv.testbay.ejb.entities.User[ id=" + username + " ]";
      }
  
  }
  </code></pre>
  
  <p><code>UserManagedBean</code> class:</p>
  
  <pre><code>@ManagedBean(name = "userManagedBean")
  @SessionScoped
  public class UserManagedBean implements Serializable {
      private static final long serialVersionUID = 1L;
  
      private User currentUser;
  
      public User getCurrentUser() {
          return currentUser;
      }
  
      public void setCurrentUser(User user) {
          this.currentUser = user;
      }
  
      public boolean isLoggedIn() {
          return currentUser != null;
      }
  
      public boolean isAdmin() {
          return currentUser != null &amp;&amp; currentUser.isAdministrator();
      }
  
      public String logout() {
          currentUser = null;
          return "/faces/index.xhtml";
      }
  
      /**
       * Creates a new instance of UserManagedBean
       */
      public UserManagedBean() {
          System.out.println("UserManagedBean constructed!");
      }
  }
  </code></pre>
  
  <p>The filter (<code>doBeforeProcessing</code>):</p>
  
  <pre><code>HttpSession session = ((HttpServletRequest) request).getSession(false);
  UserManagedBean userManagedBean = (session != null) ? (UserManagedBean) session.getAttribute("userManagedBean") : null;
  
  if (userManagedBean == null || userManagedBean.getCurrentUser() == null) {
      ((HttpServletResponse)response).sendRedirect(((HttpServletRequest) request).getContextPath() + "/faces/login.xhtml");
  }
  </code></pre>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>It is important to note that the user is properly set once, and transition to the welcome screen happens as it should. However, the nex request finds the user property empty.</p>
  
  <p>The code triggering the authentication is in the request scoped <code>LoginManagedBean</code> class:</p>
  
  <pre><code>@ManagedBean
  @RequestScoped
  public class LoginManagedBean implements Serializable {
  
      @EJB
      private AuthenticationSessionBeanLocal authBean;
  
      @ManagedProperty("#{userManagedBean}")
      private UserManagedBean userManagedBean;
  
      @PostConstruct
      public void Dummy() {
          User user = userManagedBean.getCurrentUser();
      }
  
      public UserManagedBean getUserManagedBean() {
          return userManagedBean;
      }
  
      public void setUserManagedBean(UserManagedBean userManagedBean) {
          this.userManagedBean = userManagedBean;
      }
  
      private String username;
      private String password;
  
      //Some getters and setters...
      //...
  
      public String login() throws NoSuchAlgorithmException {
          if (authenticate(username, password)) {
              if (userManagedBean.getCurrentUser().isAdministrator())
                  return "/faces/admin/welcome.xhtml?faces-redirect=true";
              else
                  return "/faces/testing/welcome.xhtml?faces-redirect=true";
          }
          return null;   
      }
  
      private boolean authenticate(String username, String password) throws NoSuchAlgorithmException {
          userManagedBean.setCurrentUser(authBean.authenticate(username, password));
          if (userManagedBean.getCurrentUser() == null)
              return false;
          return true;
      }
  
      //Constructor and methods...
      //...
  }
  </code></pre>