@ EJB en @ViewScoped @ManagedBean hace que java.io.NotSerializableException

He leído@ EJB en @ViewScoped bean gestionado causa java.io.NotSerializableException, pero mi configuración de ahorro de estado esserver.

Esto es lo que tengo:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>sispra</display-name>
    <welcome-file-list>
        <welcome-file>index.jsf</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>

    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.BUILD_BEFORE_RESTORE</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>glass-x</param-value>
    </context-param>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Secure Application</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>fileRealm</realm-name>
    </login-config>
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <security-role>
        <role-name>user</role-name>
    </security-role>
</web-app>

customer.xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<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:p="http://primefaces.org/ui">      

    <h:head>
        <title>TODO supply a title</title>
    </h:head>

    <h:body>

        <p:growl id="messages"/>

        <h:form>

            <p:commandButton actionListener="#{customerController.create}" value="save" update="@form :messages"/>

            <p:panel>
                <f:facet name="header">
                    <h:outputText value="Details"/>
                </f:facet>

                <h:panelGrid columns="3">

                    <h:outputLabel for="name" value="#{bundle['person.name']}"/>
                    <p:inputText id="name" label="#{bundle['person.name']}" value="#{customerController.selected.name}"/>
                    <p:message for="name"/>

                    <h:outputLabel for="surname" value="#{bundle['person.surname']}"/>
                    <p:inputText id="surname" label="#{bundle['person.surname']}" value="#{customerController.selected.surname}"/>
                    <p:message for="surname"/>

                </h:panelGrid>
            </p:panel>

        </h:form>

    </h:body>
</html>

CustomerController.java:

package it.shape.sispra.controllers;

import it.shape.sispra.ejb.PersonFacade;
import it.shape.sispra.entities.Customer;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class CustomerController extends AbstractController<Customer>
{
    private static final long serialVersionUID = 134755304347034L;

    @EJB
    private PersonFacade facade;

    public CustomerController()
    {
        super(Customer.class);
    }

    @Override
    public PersonFacade getFacade()
    {
        return facade;
    }
}

PersonFacade.java:

package it.shape.sispra.ejb;

import it.shape.sispra.entities.Person;
import javax.ejb.Stateless;

@Stateless
public class PersonFacade extends AbstractFacade<Person>
{
    private static final long serialVersionUID = 4357823648345L;

    public PersonFacade()
    {
        super(Person.class);
    }

}

AbstractFacade.java:

package it.shape.sispra.ejb;

import it.shape.sispra.entities.AbstractEntity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.queries.QueryByExamplePolicy;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;

public abstract class AbstractFacade<T extends AbstractEntity> implements Serializable
{
    private static final long serialVersionUID = 12467890452346123L;

    @PersistenceContext(unitName = "sispra")
    private EntityManager em;

    private final Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass)
    {
        this.entityClass = entityClass;
    }

    public EntityManager getEntityManager()
    {
        return em;
    }

    public void create(T entity)
    {
        getEntityManager().persist(entity);
    }

    public void edit(T entity)
    {
        getEntityManager().merge(entity);
    }

    public void remove(T entity)
    {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public void refresh(T entity)
    {
        getEntityManager().refresh(entity),;
    }

    public T find(Object id)
    {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll()
    {
        CriteriaQuery<T> cq = getEntityManager().getCriteriaBuilder().createQuery(entityClass);
        cq.select(cq.from(entityClass));

        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int first, int max)
    {
        CriteriaQuery<T> cq = getEntityManager().getCriteriaBuilder().createQuery(entityClass);
        cq.select(cq.from(entityClass));

        TypedQuery<T> q = getEntityManager().createQuery(cq);
        q.setMaxResults(max);
        q.setFirstResult(first);

        return q.getResultList();
    }

    public int count()
    {
        CriteriaQuery<Long> cq = getEntityManager().getCriteriaBuilder().createQuery(Long.class);
        Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        TypedQuery<Long> q = getEntityManager().createQuery(cq);
        return q.getSingleResult().intValue();
    }

    @SuppressWarnings("unchecked")
    public T findByExample(T entity)
    {
        // Create a native EclipseLink query using QBE policy
        QueryByExamplePolicy policy = new QueryByExamplePolicy();
        policy.addSpecialOperation(String.class, "like");

        ReadObjectQuery roq = new ReadObjectQuery(entity, policy);

        // Wrap the native query in a standard JPA Query and execute it
        Query query = JpaHelper.createQuery(roq, getEntityManager());

        return (T) query.getSingleResult();
    }

    @SuppressWarnings("unchecked")
    public List<T> findAllByExample(T entity)
    {
        // Create a native EclipseLink query using QBE policy
        QueryByExamplePolicy policy = new QueryByExamplePolicy();
        policy.addSpecialOperation(String.class, "like");

        ReadAllQuery raq = new ReadAllQuery(entity, policy);

        // Wrap the native query in a standard JPA Query and execute it
        Query query = JpaHelper.createQuery(raq, getEntityManager());

        return query.getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<T> findByExample(T entity, int start, int max)
    {
        // Create a native EclipseLink query using QBE policy
        QueryByExamplePolicy policy = new QueryByExamplePolicy();
        policy.addSpecialOperation(String.class, "like");

        ReadAllQuery raq = new ReadAllQuery(entity, policy);

        // Wrap the native query in a standard JPA Query and execute it
        Query query = JpaHelper.createQuery(raq, getEntityManager());
        query.setFirstResult(start);
        query.setMaxResults(max);

        return query.getResultList();
    }

    public int countByExample(T entity)
    {
        //TODO find a better way...
        return findAllByExample(entity).size();
    }
}

y este es el stacktrace:

GRAVE: Exiting serializeView - Could not serialize state: com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate
java.io.NotSerializableException: com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
  at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
  at java.util.HashMap.writeObject(HashMap.java:1001)
  at sun.reflect.GeneratedMethodAccessor45.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
  at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
  at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
  at java.util.HashMap.writeObject(HashMap.java:1001)
  at sun.reflect.GeneratedMethodAccessor45.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
  at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
  at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
  at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.serializeView(ServerSideStateCacheImpl.java:357)
  at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.saveSerializedViewInServletSession(ServerSideStateCacheImpl.java:220)
  at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.saveSerializedView(ServerSideStateCacheImpl.java:798)
  at org.apache.myfaces.renderkit.html.HtmlResponseStateManager.saveState(HtmlResponseStateManager.java:127)
  at org.apache.myfaces.application.StateManagerImpl.saveView(StateManagerImpl.java:166)
  at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1554)
  at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:281)
  at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:85)
  at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:239)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:191)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
  at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
  at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
  at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
  at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
  at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
  at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
  at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
  at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
  at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
  at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
  at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
  at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
  at java.lang.Thread.run(Thread.java:662)

Sé que puedo solucionar esto declarandoPersonFacade comotransient y uso JNDI para obtener la referencia EJB después de la reconstrucción, pero realmente no me gusta este enfoque.

¿Es posible que Glassfish 3.1.1 proporcione EJB no serializables? ¿Hay alguna manera de usar@EJB y@ViewScoped juntos?

actualizar encontré que este es un problema relacionado con MyFaces, todo funciona bien usando mojarra

Respuestas a la pregunta(2)

Su respuesta a la pregunta