title: Spring, Spring-MVC : Migrate XML configuration to Java giving data source not found error
body: <p>I am working on migrating Spring-MVC XML configuration to Java configuration. We have a lot of configuration such as locale, cache, multi-part, spring-security which is using XML. As of now Spring-security configuration is not required to be in Java, but mainly root-context.xml and servlet-context.xml. After going through other users configuration, I have added some configuration on my own, but having some issues during migration. </p>
  
  <p>One main issue is we are using 2 sessionFactory instances in XML configuration, each for a specific purpose, which are referred in DAO layer. I would like to maintain that in Java configuration as well. Thank you.</p>
  
  <p>Error :</p>
  
  <pre><code>Caused by: 
  org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'dataSource' is defined
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:704)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
  </code></pre>
  
  <p>WebConfig.java :</p>
  
  <pre><code>@Configuration
  @EnableWebMvc
  @ComponentScan(basePackages = {"com.ourapp.spring"})
  @EnableTransactionManagement
  @EnableCaching
  public class WebConfig extends WebMvcConfigurerAdapter {
  
      @Override
      public void addArgumentResolvers(List&lt;HandlerMethodArgumentResolver&gt; argumentResolvers) {
      }
  
  
      @Override
      public void configureMessageConverters(List&lt;HttpMessageConverter&lt;?&gt;&gt; converters) {
      }
  
      @Bean
      public ReloadableResourceBundleMessageSource messageSource(){
          ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
          messageSource.setBasename("../resources/locale/messages.properties");
          messageSource.setDefaultEncoding("UTF-8");
          return messageSource;
      }
  
      @Bean
      public LocaleChangeInterceptor localeInterceptor(){
          LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
          interceptor.setParamName("lang");
          return interceptor;
      }
  
      @Bean
      public MappingJackson2HttpMessageConverter converter() {
          return new MappingJackson2HttpMessageConverter();
      }
  
      @Override
      public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
          configurer.enable();
      }
  
      @Override
      public void addResourceHandlers(ResourceHandlerRegistry registry) {
          registry.addResourceHandler("/css/**").addResourceLocations("/css/");
          registry.addResourceHandler("/img/**").addResourceLocations("/img/");
          registry.addResourceHandler("/js/**").addResourceLocations("/js/");
      }
  
      @Bean
      public InternalResourceViewResolver getInternalResourceViewResolver() {
          InternalResourceViewResolver resolver = new InternalResourceViewResolver();
          resolver.setPrefix("../webapp/WEB-INF/views/jsp/");
          resolver.setSuffix(".jsp");
          return resolver;
      }
  
      @Bean
      public DoNotTruncateMyUrls doNotTruncate(){
         return new DoNotTruncateMyUrls();
      }
  
      @Bean
      public MultipartResolver multipartResolver() {
          return new StandardServletMultipartResolver();
      }
  
      @Bean
      public DataSource getNormalDataSource(){
          HikariConfig config = new HikariConfig();
          config.setJdbcUrl("jdbc:postgresql://localhost:PORT/DB_NAME");
          config.setUsername("USERNAME");
          config.setPassword("PASSWORD");
          config.addDataSourceProperty("cachePrepStmts", "true");
          config.addDataSourceProperty("prepStmtCacheSize", "250");
          config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
          return new HikariDataSource(config);
      }
  
      @Bean(name = "sessionFactory_origin")
      public DataSource getSecondaryDataSource(){
          HikariConfig config = new HikariConfig();
          config.setJdbcUrl("jdbc:postgresql://localhost:PORT/DB_NAME");
          config.setUsername("USERNAME");
          config.setPassword("PASSWORD");
          config.addDataSourceProperty("cachePrepStmts", "true");
          config.addDataSourceProperty("prepStmtCacheSize", "250");
          config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
          return new HikariDataSource(config);
      }
  
  }
  </code></pre>
  
  <p>AppInitializer.java :</p>
  
  <pre><code>public class AppInitializer implements WebApplicationInitializer {
      @Override
      public void onStartup(ServletContext container) throws ServletException {
  
          AnnotationConfigWebApplicationContext context = new
                  AnnotationConfigWebApplicationContext();
          context.register(WebConfig.class);
          container.addListener(new ContextLoaderListener(context));
          context.setServletContext(container);
          ServletRegistration.Dynamic servlet = container.addServlet("dispatcher",
                  new DispatcherServlet(context));
          servlet.setLoadOnStartup(1);
          servlet.addMapping("*.");
      }
  }
  </code></pre>
  
  <p>root-context.xml :</p>
  
  <pre><code>&lt;beans:bean id="hibernate4AnnotatedSessionFactory_extended"
                  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"&gt;
          &lt;beans:property name="dataSource" ref="extended_transactions_data_source"/&gt;
          &lt;beans:property name="packagesToScan" value="com.ourapp.spring.model"/&gt;
          &lt;beans:property name="hibernateProperties"&gt;
              &lt;beans:props&gt;
                  &lt;beans:prop key="hibernate.dialect"&gt;org.hibernate.dialect.USERNAMEQL9Dialect&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.show_sql"&gt;false&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.jdbc.batch_size"&gt;50&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/beans:prop&gt;
                  &lt;beans:prop key="cache.use_second_level_cache"&gt;true&lt;/beans:prop&gt;
                  &lt;beans:prop key="cache.use_query_cache"&gt;true&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.order_updates"&gt;true&lt;/beans:prop&gt;
                  &lt;beans:prop key="show_sql"&gt;false&lt;/beans:prop&gt;
                  &lt;beans:prop key="connection.release_mode"&gt;after_statement&lt;/beans:prop&gt;
              &lt;/beans:props&gt;
          &lt;/beans:property&gt;
      &lt;/beans:bean&gt;--&gt;
  
  
       &lt;!-- &lt;beans:bean id="extended_transactions_data_source" class="com.zaxxer.hikari.HikariDataSource"  destroy-method="close"&gt;
          &lt;beans:property name="dataSourceClassName" value="org.USERNAMEql.ds.PGSimpleDataSource"/&gt;
          &lt;beans:property name="maximumPoolSize" value="5" /&gt;
          &lt;beans:property name="maxLifetime" value="0" /&gt;
          &lt;beans:property name="idleTimeout" value="0" /&gt;
          &lt;beans:property name="connectionTimeout" value="0"/&gt;
          &lt;beans:property name="dataSourceProperties"&gt;
              &lt;beans:props&gt;
                  &lt;beans:prop key="url"&gt;jdbc:USERNAMEql://localhost:5432/DB_NAME&lt;/beans:prop&gt;
                  &lt;beans:prop key="user"&gt;USERNAME&lt;/beans:prop&gt;
                  &lt;beans:prop key="password"&gt;PASSWORD&lt;/beans:prop&gt;
              &lt;/beans:props&gt;
          &lt;/beans:property&gt;
      &lt;/beans:bean&gt;
  
  
      &lt;tx:annotation-driven transaction-manager="transactionManager_extended"/&gt;
  
      &lt;beans:bean id="transactionManager_extended" class="org.springframework.orm.hibernate4.HibernateTransactionManager"&gt;
          &lt;beans:property name="sessionFactory" ref="sessionFactory_extended"/&gt;
      &lt;/beans:bean&gt;
  
  
      &lt;beans:bean id="sessionFactory_extended" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"&gt;
          &lt;beans:property name="dataSource" ref="extended_transactions_data_source" /&gt;
          &lt;beans:property name="packagesToScan" value="com.ourapp.spring.model"/&gt;
          &lt;beans:property name="hibernateProperties"&gt;
              &lt;beans:props&gt;
                  &lt;beans:prop key="hibernate.dialect"&gt;org.hibernate.dialect.USERNAMEQL9Dialect&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.show_sql"&gt;false&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.jdbc.batch_size"&gt;50&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/beans:prop&gt;
                  &lt;beans:prop key="cache.use_second_level_cache"&gt;true&lt;/beans:prop&gt;
                  &lt;beans:prop key="cache.use_query_cache"&gt;true&lt;/beans:prop&gt;
                  &lt;beans:prop key="hibernate.order_updates"&gt;true&lt;/beans:prop&gt;
                  &lt;beans:prop key="show_sql"&gt;false&lt;/beans:prop&gt;
                  &lt;beans:prop key="connection.release_mode"&gt;after_statement&lt;/beans:prop&gt;
              &lt;/beans:props&gt;
          &lt;/beans:property&gt;
      &lt;/beans:bean&gt;--&gt;
  </code></pre>
  
  <p>Example DAOImpl :</p>
  
  <pre><code>@Repository
  @Transactional
  public class RepliesDAOImpl implements RepliesDAO {
  
      @Autowired
      @Qualifier(value = "sessionFactory_origin")
      private final SessionFactory sessionFactory;
      @Autowired
      @Qualifier(value = "sessionFactory_extended")
      private final SessionFactory sessionFactory_extended;
      @Autowired
      public RepliesDAOImpl(@Qualifier("sessionFactory_origin") SessionFactory sessionFactory, @Qualifier("sessionFactory_extended") SessionFactory sessionFactory_extended) {
          this.sessionFactory = sessionFactory;
          this.sessionFactory_extended = sessionFactory_extended;
      }
  //Methods in the class
  }
  </code></pre>
  
  <p>I have also added entire configs in Pastebin <a href="https://pastebin.com/WW4THY6E" rel="nofollow noreferrer">root-context.xml</a></p>
  
  <p><a href="https://pastebin.com/k3tJJxuA" rel="nofollow noreferrer">servlet-context.xml</a></p>
  
  <p><em>Update replies DAOImpl</em></p>
  
  <pre><code>@Repository
  @Transactional
  public class RepliesDAOImpl implements RepliesDAO {
  
      @Autowired
      @Qualifier(value = "dataSource")
      private DataSource dataSource;
  
      @Bean()
      @Qualifier("sessionFactory_origin")
      public LocalSessionFactoryBean sessionFactory() {
          LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
          sessionFactory.setDataSource(dataSource);
          sessionFactory.setPackagesToScan(
                  new String[] { "com.ourapp.spring" });
          return sessionFactory;
      }
  
  
   @Override
      public Long addReply(Replies replies, int conversationId, Person person) {
          SessionFactory sessi = (SessionFactory) sessionFactory();
          Session session = this.sessionFactory.getCurrentSession();
  }
      @Autowired
      @Qualifier(value = "sessionFactory_origin")
      private final SessionFactory sessionFactory;
  
      @Autowired
      @Qualifier(value = "sessionFactory_extended")
      private final SessionFactory sessionFactory_extended;
      @Autowired
      public RepliesDAOImpl(@Qualifier("sessionFactory_origin") SessionFactory sessionFactory, @Qualifier("sessionFactory_extended") SessionFactory sessionFactory_extended) {
          this.sessionFactory = sessionFactory;
          this.sessionFactory_extended = sessionFactory_extended;
      }
  </code></pre>
  
  <p><em>Updated webconfig</em></p>
  
  <pre><code>@Bean(name = "sessionFactory_origin")
      @Qualifier("dataSource")
      public DataSource getNormalDataSource(){
     // Bean definition
  }
  
   @Qualifier("extended_data_source")
      @Bean(name ="extended_dataSource" )
      public DataSource getSecondaryDataSource(){
  //Secondary data source
  }
  </code></pre>