title: SFSB being removed
body: <p>I'm using JBoss6.1.Final, JSF 2.0 (Mojarra), Weld CDI, MyFaces CODI 1.0.5 (for view-access-scoped)</p>
  
  <p>I'm using something like the Gateway Pattern from <a href="https://rads.stackoverflow.com/amzn/click/com/0557078326" rel="nofollow noreferrer" rel="nofollow noreferrer">Real World Java EE Patterns Rethinking Best Practices</a> (unfortunately I don't have it with me, so I may have screwed something up here).  Basically, the application allows a user to go into "edit mode" and edit a List of people (create, edit, remove) maintained in a @ViewAccessScoped backing bean with an extended persistence context and then click a "save" command link that flushes all their changes to the database.  At first I was having a problem with ViewExpiredExceptions (if the browser was idle past the session-timeout period and then further requests are performed), but I added some jQuery to make a get request to a servlet that keeps the session alive (called 10 seconds before session-timeout).  This seems to be working but now I have another problem, the backing bean is also a SFSB and after some idle time, it is being removed resulting in the following error message being logged (and all ajax rendered data disappears) when I attempt to perform more edits ...</p>
  
  <p>13:06:22,063 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] javax.el.ELException: /index.xhtml @27,81 rendered="#{!conversationBean.editMode}": javax.ejb.NoSuchEJBException: Could not find stateful bean: 43h1h2f-9c7qkb-h34t0f34-1-h34teo9p-de</p>
  
  <p>Any ideas on how I could prevent SFSB removal or at least handle it more gracefully?</p>
  
  <p>Here's my backing bean:</p>
  
  <pre><code>package com.ray.named;
  
  import java.io.Serializable;
  import java.util.List;
  
  import javax.annotation.PostConstruct;
  import javax.ejb.EJBTransactionRolledbackException;
  import javax.ejb.Stateful;
  import javax.ejb.TransactionAttribute;
  import javax.inject.Named;
  import javax.persistence.EntityManager;
  import javax.persistence.PersistenceContext;
  import javax.persistence.PersistenceContextType;
  
  import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;
  
  import com.ray.model.Person;
  
  @Named
  @Stateful
  @ViewAccessScoped
  @TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
  public class ConversationBean implements Serializable {
    private static final long serialVersionUID = 1L;
    //properties
    private List&lt;Person&gt; people;
    private String name;
    private Boolean editMode;
  
    @PersistenceContext(type=PersistenceContextType.EXTENDED)
    private EntityManager em;
  
    @PostConstruct
    public void init() {
      people = em.createNamedQuery("Person.findAll", Person.class).getResultList();
      setEditMode(false);
    }
  
    //event listeners
    public void beginEdits() {
      setEditMode(true);
    }
  
    public void addPerson() {
      Person p = new Person(name);
      em.persist(p);
      people.add(p);
      name = null;
    }
  
    public void removePerson(Person p) {
      people.remove(people.indexOf(p));
      em.remove(p);
    }
  
    //this method flushes the persistence context to the database
    @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
    public void saveEdits() {
      setEditMode(false);
    }
  
    //getters/setters
    public List&lt;Person&gt; getPeople() {
      return people;
    }
  
    public String getName() {
      return name;
    }
  
    public void setName(String name) {
      this.name = name;
    }
  
    public Boolean getEditMode() {
      return editMode;
    }
  
    public void setEditMode(Boolean editMode) {
      this.editMode = editMode;
    }
  }
  </code></pre>
  
  <p>Here's the Person entity bean:</p>
  
  <pre><code>package com.ray.model;
  
  import javax.persistence.Entity;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.NamedQueries;
  import javax.persistence.NamedQuery;
  import javax.persistence.Version;
  
  @Entity
  @NamedQueries({
    @NamedQuery(name="Person.findAll",
                query="SELECT p FROM Person p")
  })
  public class Person {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Integer id;
    private String name;
    @Version
    private int version;
  
    public Person() { }
  
    public Person(String name) {
      setName(name);
    }
  
    public boolean equals(Object o) {
      if (!(o instanceof Person)) {
        return false;
      }
      return id == ((Person)o).id;
    }
  
    //getters/setters
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name = name;
    }
  
    public Integer getId() {
      return id;
    }
  
    public int getVersion() {
      return version;
    }
  
    public void setVersion(int version) {
      this.version = version;
    }
  }
  </code></pre>
  
  <p>Here's the view:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets"&gt;
  &lt;h:head&gt;
    &lt;script src="http://code.jquery.com/jquery-latest.min.js"&gt;&lt;/script&gt;
    &lt;script&gt;
    $(document).ready(function() {
      setInterval(function() {
        $.get("#{request.contextPath}/poll");
      }, #{(session.maxInactiveInterval - 10) * 1000});
    });
    &lt;/script&gt;
    &lt;title&gt;Conversation Test&lt;/title&gt;
  &lt;/h:head&gt;
  &lt;h:body&gt;
    &lt;h:form&gt;
      &lt;h:commandLink value="Begin Edits" rendered="#{!conversationBean.editMode}"&gt;
        &lt;f:ajax render="@form" listener="#{conversationBean.beginEdits}"/&gt;
      &lt;/h:commandLink&gt;
      &lt;h:commandLink value="Save" rendered="#{conversationBean.editMode}"&gt;
        &lt;f:ajax render="@form" listener="#{conversationBean.saveEdits}"/&gt;
      &lt;/h:commandLink&gt;
      &lt;h:dataTable id="peopleTable" value="#{conversationBean.people}" var="person"&gt;
        &lt;h:column&gt;
          &lt;f:facet name="header"&gt;Name&lt;/f:facet&gt;
          &lt;h:panelGroup&gt;
            &lt;h:inputText value="#{person.name}" disabled="#{!conversationBean.editMode}"&gt;
              &lt;f:ajax/&gt;
            &lt;/h:inputText&gt;
            &lt;h:commandLink value="X" disabled="#{!conversationBean.editMode}"&gt;
              &lt;f:ajax render="@form" listener="#{conversationBean.removePerson(person)}"/&gt;
            &lt;/h:commandLink&gt;
          &lt;/h:panelGroup&gt;
        &lt;/h:column&gt;
      &lt;/h:dataTable&gt;
      &lt;h:panelGrid columns="2"&gt;
        &lt;h:outputLabel for="name"&gt;Name:&lt;/h:outputLabel&gt;
        &lt;h:inputText id="name" value="#{conversationBean.name}" disabled="#{!conversationBean.editMode}"/&gt;
      &lt;/h:panelGrid&gt;
      &lt;h:commandButton value="Add" disabled="#{!conversationBean.editMode}"&gt;
        &lt;f:ajax execute="@form" render="@form" listener="#{conversationBean.addPerson}"/&gt;
      &lt;/h:commandButton&gt;
    &lt;/h:form&gt;
  &lt;/h:body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Here's a servlet used to keep the session alive (called by jQuery ajax get request 10 seconds before session expires):</p>
  
  <pre><code>package com.ray.web;
  
  import java.io.IOException;
  
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  public class PollServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
  
    public void init() throws ServletException {
    }
  
    public String getServletInfo() {
      return null;
    }
  
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
      request.getSession(); //Keep session alive
    }
  
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    }
  
    public void destroy() {
    }
  }
  </code></pre>