2010-10-03 16 views
9

Hola estoy usando ViewScoped Bean el problema es que cuando lo llamo obtengo la NotSerializableException.ViewScoped Bean causa NotSerializableException

Este es el código de mi bean gestionado:

@ManagedBean(name="demandesBean") 
@ViewScoped 
public class DemandesBean implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @ManagedProperty(value="#{demandeService}") 
    private DemandeService demandeService; //A Spring Service 

    @ManagedProperty(value="#{loginBean}") 
    private LoginBean loginBean; 

    private DemandeVO newDemande; 

    @PostConstruct 
    public void initData() { 
     newDemande = new DemandeVO(); 
    } 

    public void doAjouterDemande(ActionListener event) { 
     demandeService.createDemande(newDemande, loginBean.getUsername()); 
     newDemande = new DemandeVO(); 
    } 

    public List<DemandeVO> getListDemande() { 
     return demandeService.getAllDemandesByUser(loginBean.getUsername()); 
    } 

    public DemandeService getDemandeService() { 
     return demandeService; 
    } 

    public void setDemandeService(DemandeService demandeService) { 
     this.demandeService = demandeService; 
    } 

    public LoginBean getLoginBean() { 
     return loginBean; 
    } 

    public void setLoginBean(LoginBean loginBean) { 
     this.loginBean = loginBean; 
    } 

    public DemandeVO getNewDemande() { 
     return newDemande; 
    } 

    public void setNewDemande(DemandeVO newDemande) { 
     this.newDemande = newDemande; 
    } 
} 

que recibo la siguiente excepción:

GRAVE: Exiting serializeView - Could not serialize state: com.bull.congesJBPM.serviceImpl.DemandeServiceImpl 
java.io.NotSerializableException: com.bull.congesJBPM.serviceImpl.DemandeServiceImpl 

Cualquier solución para este problema ?? Por favor ayuda !

+1

Pregunta muy similar, con resolución, aquí: http://stackoverflow.com/questions/3180963/spring-session-scoped-beans-controllers-and-references-to-services-in-terms-of – skaffman

Respuesta

6

Otro problema es que MyFaces por defecto tiene serialización de estado, incluso cuando el estado se guarda en el servidor (por defecto). Esto en su turno requiere ver los beans de respaldo con ámbito ser serializables.

Los pros de este enfoque es que la historia es realmente historia. Cuando vuelve a una versión de vista anterior (usando el botón Atrás), en realidad obtiene la versión exacta del bean de respaldo en ese momento.

La desventaja es que parece interrumpir la inyección de servicios (y no relacionado con este problema, es un gran golpe de rendimiento). Los mismos problemas ocurren cuando se inyecta un servicio EJB.

Hay un parámetro de contexto que se puede poner en web.xml para desactivar este comportamiento:

<context-param> 
    <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name> 
    <param-value>false</param-value> 
</context-param> 

Ver http://wiki.apache.org/myfaces/Performance

Por cierto, Mojarra tiene una configuración similar pero no el valor predeterminado es falso.

0

He publicado una solución para este problema en my own question about this same problem, que dice así: en lugar de inyectar los granos de primavera a través de EL en una @ManagedProperty anotación (ejecutado en la inicialización ManagedBean), se obtienen los granos que evalúan la EL en tiempo de ejecución.

Con este enfoque, el bean JSF debería tener este aspecto:

@ManagedBean(name="demandesBean") 
@ViewScoped 
public class DemandesBean implements Serializable { 
    private static final long serialVersionUID = 1L; 

    private static DemandeService demandeService() { 
     return SpringJSFUtil.getBean("demandeService"); 
    } 

    // ... 
    public void doAjouterDemande(ActionListener event) { 
     demandeService().createDemande(newDemande, loginBean.getUsername()); 
     newDemande = new DemandeVO(); 
    } 
    // ... 

Y aquí es la clase de utilidad utilizado SpringJSFUtil.java:

import javax.faces.context.FacesContext; 

public class SpringJSFUtil { 

    public static <T> T getBean(String beanName) { 
     if (beanName == null) { 
      return null; 
     } 
     return getValue("#{" + beanName + "}"); 
    } 

    @SuppressWarnings("unchecked") 
    private static <T> T getValue(String expression) { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     return (T) context.getApplication().evaluateExpressionGet(context, 
       expression, Object.class); 
    } 
} 

Esto elimina la propiedad de bean primavera (a costa de hacer algunas evaluaciones EL más), evitando así los problemas de serialización de tener la propiedad en primer lugar.

0

Todo en ViewScoped bean se almacena en ViewState. Puede desactivar la serialización de ViewState en sesión, pero las sesiones pueden ser serializadas y luego el problema surgirá en otro lugar.

La solución con Spring es para Serializable Proxy.

<aop:scoped-proxy proxy-target-class="true"/> 

granos de primavera están envueltos en proxy, que es serializable, y la referencia envuelta es transitorio, por lo que se vuelve a leer a partir del contexto primavera después de deserialización.

Es técnicamente similar a la respuesta elias, solo usted no necesita escribir ese código para cada bean. Utiliza aop.

Puedes ver mi pregunta: JSF beans and serializability issue para obtener más contexto.

Cuestiones relacionadas