title: Spring with JSF 2 view scope losing injected values
body: <p>I have implemented the custom view scope for spring. The page was a redirect from another bean with prerenderView listener that loads a p:datatable. The datatable is loaded with the values and then there is a p:command button to submit the data to a backing bean that calls a service to use the dao implement to update a table. The daoImpl has none of the injected properties now. Datasource and jdbctemplate are now null. I believe I have everything configured to let Spring managed my beans but it seems to me a new instance of the bean is created and spring is not aware therefore doesn't inject the values. Code below has been simplified.</p>
  
  <p>Page
          
          
          
          
      </p>
  
  <pre><code>&lt;ui:define name="content"&gt;
      &lt;h:form id="form1" &gt;
  
         &lt;p:messages id="msgs" autoUpdate="true"/&gt; 
  
          &lt;p:panel id="panel1" &gt;
          &lt;center&gt;
  
              &lt;p:dataTable id="campaignQTable" var="campaignQ" value="#{campaign.campaignQRows}"
                        style="text-align:right"  editable="true"  &gt; 
                       &lt;!-- paginator="true" rows="10"  
                       paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} 
                          {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"  
                       rowsPerPageTemplate="5,10,15" &gt;  
  
                       widgetVar="scrollist"&gt;
                      scrollable="true"  scrollWidth="1100"&gt;  
  
                       --&gt;  
  
              &lt;f:facet name="header"&gt;  
                  Update Campaign Qualifications
              &lt;/f:facet&gt;  
  
               &lt;p:column headerText="Contest Name" style="text-align:center"&gt;
                  &lt;h:outputText value="#{campaignQuals.contestName}" /&gt;
              &lt;/p:column&gt;
  
  
          &lt;/p:dataTable&gt;
  
           &lt;p:commandButton value="Save Campaign Qualifications" action="#{campaign.saveCampaignQuals}" 
               process="@all" update="msgs,panel1" /&gt;
  
          &lt;/center&gt;
          &lt;/p:panel&gt;
  
      &lt;/h:form&gt;
  </code></pre>
  
  <p>Bean</p>
  
  <pre><code>@Component("campaign")
  @Scope("view")
  public class CampaignQualBeans implements Serializable {
  
      private static final long serialVersionUID = 1L;
  
      @Autowired
      @Qualifier("CampaignServiceImpl")
      CampaignService campaignService;
  
      //  CampaignQualsTblId - all rows
      ArrayList&lt;CampaignQualsTblId&gt; campaignQNames = new ArrayList&lt;CampaignQualsTblId&gt;();
      CampaignQualsTblId selectedCampaignQ;
  
      String contestName;
      String contestYear;
      String conYearPlus1;
  
      //  CampaignQualsTbl - single Campaign all rows for a single year
      ArrayList&lt;CampaignQualsTbl&gt; campaignQRows = new ArrayList&lt;CampaignQualsTbl&gt;();
  
      // *************************************************************
      // CONSTRUCTORS ************************************************
      // *************************************************************
  
      public CampaignQualBeans() {
          super();        
      }       
  
  
  
  
      //  Upon listener being running, get all the rows for that contest year (campaignQualsUpdate.xhtml)
      public void loadCampaignQuals(ComponentSystemEvent event) {
  
          if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
              return;
  
          }else{  
              System.out.println("Campaign Qualifications Loaded");
              campaignQRows = campaignService.getCampaignQualRows(contestName, contestYear);
  
              int year = Integer.parseInt(contestYear) + 1;
              conYearPlus1 = String.valueOf(year);
  
          }
      }
  
      //  Once button has been selected, save the data to the CampaignQualsTbl (campaignQualsUpdate.xhtml)
      public String saveCampaignQuals() {
          System.out.println("Contest Saved");
  
          boolean success = campaignService.saveCampaignQRows(contestName, contestYear, campaignQRows);
  
          if (success) {
              FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Campaign Qualifications were successfully entered for " 
                      + contestName + " - " + contestYear));
          }
          else {
  
              FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Campaign Qualifications were not saved.  Please check entry and save again.  " + 
               "If the problem continues, please contact the Help Desk.",""));
          }
          return null;
      }
  }
  
  view scope
  
      public class ViewScope implements Scope{
  
      public Object get(String name, ObjectFactory objectFactory) {
          Map&lt;String,Object&gt; viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
  
          if(viewMap.containsKey(name)) {
              return viewMap.get(name);
          } else {
              Object object = objectFactory.getObject();
              viewMap.put(name, object);
  
              return object;
          }
      }
  
      public Object remove(String name) {
          return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
      }
  
      public String getConversationId() {
          return null;
      }
  
      public void registerDestructionCallback(String name, Runnable callback) {
          //Not supported
      }
  
      public Object resolveContextualObject(String key) {
          return null;
      }       
  }
  </code></pre>
  
  <p>Service</p>
  
  <pre><code>    @Service("CampaignServiceImpl")
  public class CampaignServiceImpl implements CampaignService,ServletContextAware,Serializable{
  
      private static final long serialVersionUID = 1L;
  
      @Autowired
      @Qualifier("campaignDao")
      CampaignDao campaignDAO;
  
  
      private transient ServletContext servletContext;
  
      //  call DAO to insert the campaign qualifications data into the Campaign_Quals_tbl table
      @Override
      public boolean saveCampaignQRows(String contestName, String contestYear,
              ArrayList&lt;CampaignQualsTbl&gt; campaignQRows) {
  
          boolean success = campaignDAO.insertCampaignQRows(contestName, contestYear, campaignQRows);
  
          return success;
      }
  
      @Override
      public void setServletContext(ServletContext arg0) {
          // TODO Auto-generated method stub
  
      }
  
  }
  </code></pre>
  
  <p>Dao</p>
  
  <pre><code>@Repository("campaignDao")
  public class CampaignDaoImpl implements CampaignDao,Serializable{
  
      private static final long serialVersionUID = 1L;
  
      @Autowired
      @Qualifier("myDataSource")
      private transient DataSource dataSource;
  
      @Autowired
      transient ServletContext context;
  
      private transient JdbcTemplate JDBCTemplate;
      private SimpleJdbcCall jdbcCall;  
  
      //setup JDBC sources/connections
      public void setUserJDBCTemplate(JdbcTemplate userJDBCTemplate) {
          this.JDBCTemplate = new JdbcTemplate(dataSource);
      }
  
      // *************************************************************
      // SQL Statements for the Campaign_Quals_tbl********************
      // *************************************************************    
      private static final String INSERT_CAMPAIGN_Q_ROW =
              "Insert into Campaign_Quals_tbl (ContestName, ContestYear, Agent_Tenure, Torunament_Level, Placed_Applications " +
              "Life_Premium, Contest_Premium, Min_Life_Premium" +
              "Values (?, ?, ?, ?, ?, ?, ?, ?)";
  
  
  
      //  execute the query that inserts the new rows into the Campaign_Quals_tbl table
      @Override
      public boolean insertCampaignQRows(String contestName, String contestYear, 
              ArrayList&lt;CampaignQualsTbl&gt; campaignQRows) {
  
          ArrayList&lt;CampaignQualsTbl&gt; rows = campaignQRows;
  
          try {
              JDBCTemplate = new JdbcTemplate(dataSource);
  
              for (CampaignQualsTbl row : rows) {
  
                  Object[] parameters = new Object[] {contestName, contestYear, row.getAgentTenure(), row.getTournamentLevel(), 
                      row.getPlacedApplications(), row.getLifePremium(), row.getContestPremium(), row.getMinLifePremium()};
  
                  JDBCTemplate.update(INSERT_CAMPAIGN_Q_ROW, parameters);
              }
  
          } catch (DataAccessException e){
                  e.printStackTrace();                
                  return false;
          }   
          return true;
      }   
  }
  </code></pre>
  
  <p>Logs</p>
  
  <pre><code>   START PHASE RESTORE_VIEW(1)
  END PHASE RESTORE_VIEW(1)
  START PHASE APPLY_REQUEST_VALUES(2)
  [DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory -   - Creating instance of bean 'campaignQuals'
  [DEBUG] - org.springframework.beans.factory.annotation.InjectionMetadata -   - Processing injected method of bean 'campaignQuals': AutowiredFieldElement for tfic.com.Campaign.service.CampaignService tfic.com.Campaign.beans.CampaignQualBean.campaignService
  [DEBUG] - org.springframework.beans.factory.support.AbstractBeanFactory -   - Returning cached instance of singleton bean 'CampaignServiceImpl'
  [DEBUG] - org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata -   - Invoking init method on bean 'campaignQuals': public void tfic.com.Campaign.beans.CampaignQualBean.loadCampaignQualNames()
  [DEBUG] - org.springframework.jdbc.core.JdbcTemplate -   - Executing SQL query [Select ContestName, Max(ContestYear) as ContestYear from Campaign_Quals_tbl group by ContestName]
  [DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils -   - Fetching JDBC Connection from DataSource
  [DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils -   - Returning JDBC Connection to DataSource
  [DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory -   - Finished creating instance of bean 'campaignQuals'
  END PHASE APPLY_REQUEST_VALUES(2)
  START PHASE PROCESS_VALIDATIONS(3)
  END PHASE PROCESS_VALIDATIONS(3)
  START PHASE UPDATE_MODEL_VALUES(4)
  END PHASE UPDATE_MODEL_VALUES(4)
  START PHASE INVOKE_APPLICATION(5)
  tfic.com.Campaign.model.CampaignQualsTblId@11d93d05
  END PHASE INVOKE_APPLICATION(5)
  START PHASE RESTORE_VIEW(1)
  END PHASE RESTORE_VIEW(1)
  START PHASE APPLY_REQUEST_VALUES(2)
  END PHASE APPLY_REQUEST_VALUES(2)
  START PHASE PROCESS_VALIDATIONS(3)
  [DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory -   - Creating instance of bean 'campaign'
  [DEBUG] - org.springframework.beans.factory.annotation.InjectionMetadata -   - Processing injected method of bean 'campaign': AutowiredFieldElement for tfic.com.Campaign.service.CampaignService tfic.com.Campaign.beans.CampaignQualBeans.campaignService
  [DEBUG] - org.springframework.beans.factory.support.AbstractBeanFactory -   - Returning cached instance of singleton bean 'CampaignServiceImpl'
  [DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory -   - Finished creating instance of bean 'campaign'
  END PHASE PROCESS_VALIDATIONS(3)
  START PHASE UPDATE_MODEL_VALUES(4)
  END PHASE UPDATE_MODEL_VALUES(4)
  START PHASE INVOKE_APPLICATION(5)
  END PHASE INVOKE_APPLICATION(5)
  START PHASE RENDER_RESPONSE(6)
  Campaign Qualifications Loaded
  [DEBUG] - org.springframework.jdbc.core.JdbcTemplate -   - Executing prepared SQL query
  [DEBUG] - org.springframework.jdbc.core.JdbcTemplate -   - Executing prepared SQL statement [Select Agent_Tenure, Tournament_Level, Placed_Applications,Life_Premium, Contest_Premium, Min_Life_Premium from Campaign_Quals_tbl where ContestName = ? and ContestYear = ?]
  [DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils -   - Fetching JDBC Connection from DataSource
  [DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils -   - Returning JDBC Connection to DataSource
  END PHASE RENDER_RESPONSE(6)
  START PHASE RESTORE_VIEW(1)
  END PHASE RESTORE_VIEW(1)
  START PHASE APPLY_REQUEST_VALUES(2)
  END PHASE APPLY_REQUEST_VALUES(2)
  START PHASE PROCESS_VALIDATIONS(3)
  END PHASE PROCESS_VALIDATIONS(3)
  START PHASE UPDATE_MODEL_VALUES(4)
  END PHASE UPDATE_MODEL_VALUES(4)
  START PHASE INVOKE_APPLICATION(5)
  Lost injection datasource and jdbctemplate
  END PHASE INVOKE_APPLICATION(5)
  </code></pre>
  
  <p>WEB.XML</p>
  
  <pre><code>  &lt;?xml version="1.0" encoding="UTF-8"?&gt;
      &lt;web-app xmlns="http://java.sun.com/xml/ns/javaee" 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" version="3.0"&gt;
      &lt;display-name&gt;SalesCampaignAdmin&lt;/display-name&gt;
      &lt;servlet&gt;
          &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
          &lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
          &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
          &lt;enabled&gt;true&lt;/enabled&gt;
          &lt;async-supported&gt;false&lt;/async-supported&gt;
      &lt;/servlet&gt;
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
          &lt;url-pattern&gt;
          *.xhtml&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
      &lt;listener&gt;
          &lt;listener-class&gt;
              org.springframework.web.context.request.RequestContextListener
          &lt;/listener-class&gt;
      &lt;/listener&gt;
  
      &lt;servlet&gt;
          &lt;servlet-name&gt;mvc-dispatcher&lt;/servlet-name&gt;
          &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
          &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
      &lt;/servlet&gt;
  
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;mvc-dispatcher&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
  
      &lt;context-param&gt;
          &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
          &lt;param-value&gt;/WEB-INF/application-context.xml&lt;/param-value&gt;
      &lt;/context-param&gt;
  
      &lt;listener&gt;
          &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
      &lt;/listener&gt;
  
        &lt;context-param&gt;
      &lt;param-name&gt;javax.faces.PARTIAL_STATE_SAVING&lt;/param-name&gt;
      &lt;param-value&gt;false&lt;/param-value&gt;
    &lt;/context-param&gt;
  
    &lt;context-param&gt;
      &lt;param-name&gt;javax.faces.FACELETS_REFRESH_PERIOD&lt;/param-name&gt;
      &lt;param-value&gt;1&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;context-param&gt;
      &lt;param-name&gt;org.apache.myfaces.ALLOW_JAVASCRIPT&lt;/param-name&gt;
      &lt;param-value&gt;true&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;context-param&gt;
      &lt;param-name&gt;org.apache.myfaces.PRETTY_HTML&lt;/param-name&gt;
      &lt;param-value&gt;true&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;context-param&gt;
      &lt;param-name&gt;org.apache.myfaces.DETECT_JAVASCRIPT&lt;/param-name&gt;
      &lt;param-value&gt;false&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;context-param&gt;
      &lt;param-name&gt;org.apache.myfaces.AUTO_SCROLL&lt;/param-name&gt;
      &lt;param-value&gt;true&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;context-param&gt;
      &lt;param-name&gt;com.sun.faces.expressionFactory&lt;/param-name&gt;
      &lt;param-value&gt;com.sun.el.ExpressionFactoryImpl&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;context-param&gt;
      &lt;param-name&gt;org.apache.myfaces.EXPRESSION_FACTORY&lt;/param-name&gt;
      &lt;param-value&gt;com.sun.el.ExpressionFactoryImpl&lt;/param-value&gt;
    &lt;/context-param&gt; 
  </code></pre>
  
  <p>Faces-config</p>
  
  <pre><code> &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;faces-config
      xmlns="http://xmlns.jcp.org/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
      version="2.2"&gt;
  
      &lt;application&gt;
          &lt;el-resolver&gt;org.springframework.web.jsf.el.SpringBeanFacesELResolver&lt;/el-resolver&gt;
      &lt;/application&gt;
  
  
  &lt;/faces-config&gt;
  </code></pre>
  
  <p>app context</p>
  
  <pre><code>&lt;beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="
              http://www.springframework.org/schema/beans     
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/context 
              http://www.springframework.org/schema/context/spring-context-3.0.xsd
              http://www.springframework.org/schema/mvc
              http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
              http://www.springframework.org/schema/tx
              http://www.springframework.org/schema/mvc/spring-tx-3.0.xsd
              http://www.springframework.org/schema/jdbc
              http://www.springframework.org/schema/mvc/spring-jdbc-3.0.xsd"&gt;
  
              &lt;context:component-scan base-package="tfic.*" /&gt; 
          &lt;mvc:annotation-driven/&gt;
      &lt;import resource="mvc-dispatcher-servlet.xml"/&gt;
      &lt;import resource="spring-datasource.xml"/&gt;
  
      &lt;bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"&gt;
              &lt;property name="scopes"&gt;
                  &lt;map&gt;
                      &lt;entry key="view"&gt;
                          &lt;bean class="tfic.com.Campaign.helpers.ViewScope"/&gt;
                      &lt;/entry&gt;
                  &lt;/map&gt;
              &lt;/property&gt;
          &lt;/bean&gt;
  
  
      &lt;/beans&gt;
  </code></pre>