Search code examples
springjsfserializableview-scope

Can't get view scope working for my ManagedBeans


I'm using JSF 2 with Spring 3 in my project and until now, I'm just using request and session scopes. I want to use view scope for some of my JSF beans (for multiple reasons).

The problem is that the JSF ManagedBean have to implement Serializable interface, and all of its properties.

I have some difficulty to get the Spring beans Serializables (ex. : VilleService...) because it continue to ask for more classes to be serializable even if it's not possible (hibernate classes or mysql ...).

Here is an example :

public class VilleBean extends BaseBean implements Serializable {

    private Ville ville;
    private List<Ville> villes;
    private VilleService villeService;
    private PaysService paysService;
    private Pays pays;
    private List<Pays> payss;
    private PojoConverter<Pays> paysConverter = null;

    public VilleBean() {
        ville = new Ville();
        pays = new Pays();
    }

    public void setVilleService(VilleService villeService) {
        this.villeService = villeService;
    }

    public void setPaysService(PaysService paysService) {
        this.paysService = paysService;
    }

    // getters and setters for attributes : ville, pays, villes, payss


    public void addVilleAction() {
         ville.setPays(pays);
         villeService.create(ville);
    }

    public void deleteVilleAction(Ville ville) {
         villeService.delete(ville);
         villes = villeService.readAll();
    }

    public void updateVilleAction() {
         ville.setPays(pays);
         villeService.update(ville);
    }

    public PojoConverter<Pays> getPaysConverter() {
        this.paysConverter = new PojoConverter<Pays>(getPayss());
        return this.paysConverter;
    }
}



public abstract class BaseBean {
    protected FacesContext context = FacesContext.getCurrentInstance();
    protected MessageFactory msg;
    protected static final Logger log = Logger.getLogger(BaseBean.class);
}

POJO :

public class Ville implements Serializable {

    private int id;
    private String intitule;
    private Pays pays;

// setters and getters
}

public class Pays implements Serializable {

    private int id;
    private String intitule;

// setters and getters
}

Service interface :

public interface VilleService extends ICrud<Ville> {

}

Service Impl :

public class VilleServiceBase implements VilleService {

private IDao<Ville> dao;

// getter and setter for dao

@Override
public List<Ville> readAll() throws Exception {
       return dao.readAll();
}

@Override
public void create(Ville entity) throws Exception {
        dao.create(entity);
}
//****

Util :

public interface ICrud<T> {

public java.util.List readAll() throws Exception;
public void create(T entity) throws Exception;
public void update(T entity) throws Exception;
//****

public interface IDao<T> {

public java.util.List<T> readAll();
public T create(T entity);
//****

public class DaoBase<T> extends org.springframework.orm.hibernate3.support.HibernateDaoSupport implements IDao<T> {

private final Class<T> type;

public DaoBase(Class<T> type) {
      this.type = type;
}

@Override
public T load(int id) {
        return (T) this.getHibernateTemplate().get(this.type, new Integer(id));
}

@Override
public T create(T entity) {
     //****
       this.getHibernateTemplate().save(entity);
       return entity;
}

Spring beans : spring.xml :

 <!-- Ville Service Implementation  -->
<bean id="villeServiceBase" class="commun.ref.crud.VilleServiceBase">
    <property name="dao">
        <ref bean="villeDao"/>
    </property>
</bean>
<!-- Ville Service Proxy  -->
<bean id="villeService" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
        <ref local="villeServiceBase"/>
    </property>
    <property name="proxyInterfaces">
        <value>commun.ref.crud.VilleService</value>
    </property>
    <property name="interceptorNames">
        <list>
            <value>manageableServiceTransactionInterceptor</value>
            <value>hibernateInterceptor</value>
        </list>
    </property>
</bean>

<bean id="villeDao" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
        <bean class="smile.util.DaoBase">
            <constructor-arg>
                <value>commun.ref.Ville</value>
            </constructor-arg>
            <property name="sessionFactory">
                <ref bean="sessionFactory"/>
            </property>
        </bean>
    </property>
    <property name="proxyInterfaces">
        <value>smile.util.IDao</value>
    </property>
    <property name="interceptorNames">
        <list>
            <value>hibernateInterceptor</value>
        </list>
    </property>
</bean>

JSF configuration : faces-config.xml :

<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

<application>
    <variable-resolver>
        org.springframework.web.jsf.DelegatingVariableResolver
    </variable-resolver>
</application>

    ******

<managed-bean> 
    <managed-bean-name>villeBean</managed-bean-name>
    <managed-bean-class>commun.ref.ui.VilleBean</managed-bean-class>
    <managed-bean-scope>view</managed-bean-scope>
    <managed-property>
        <property-name>villeService</property-name>
        <value>#{villeService}</value>
    </managed-property>
    <managed-property>
        <property-name>paysService</property-name>
        <value>#{paysService}</value>
    </managed-property>
</managed-bean>

Can you tell me please, what to do to get this to work.


Solution

  • On fields which you don't want to be serialized or they can't be serialized use transient modifier. For example:

    private transient VilleService villeService;
    

    As you are using MyFaces add this parameter to web.xml:

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

    As I know this parameter is default false in Mojarra. This will disable serialization of state in session.