title: Spring 4 @Configuration order for setting up JPA
body: <p>I had a working Jersey 2.2 applisaction with Spring 4 in which I was using Eclipselink as JPA implementation.</p>
  
  <p>The application config calss looks as follows:</p>
  
  <pre><code>@Configuration
  @ComponentScan(value = "com.nws.vedica", lazyInit = true)
  @PropertySource({"classpath:swagger.properties", "classpath:vedica.properties"})
  @ApplicationPath("/api")
  
  public class VedicaConfig extends ResourceConfig {
  
  public VedicaConfig() {
      packages("com.nws.vedica");
      property(ServletProperties.FILTER_FORWARD_ON_404, true);
      register(MultiPartFeature.class);
      register(JacksonFeature.class);
      register(ValidationFeature.class);
      register(ValidationConfigurationContextResolver.class);
      register(PropertySourcesPlaceholderConfigurer.class);
  
      register(ApiListingResource.class);
      register(SwaggerSerializers.class);
  }
  }
  </code></pre>
  
  <p>The JPA configuration class:</p>
  
  <pre><code>@Configuration
  @EnableTransactionManagement
  public class JPAConfig {
  
  private Map&lt;String, String&gt; properties;
  
  @Value("${db.url}")
  private String dbConnectionURL;
  
  @Value("${db.user}")
  private String dbUser;
  
  @Value("${db.pass}")
  private String dbPassword;
  
  @PostConstruct
  public void init() {
      properties = new HashMap&lt;&gt;();
      properties.put("javax.persistence.jdbc.url", dbConnectionURL);
      properties.put("javax.persistence.jdbc.user", dbUser);
      properties.put("javax.persistence.jdbc.password", dbPassword);
      properties.put("javax.persistence.jdbc.driver", "org.postgresql.Driver");
      properties.put("javax.persistence.target-database", "PostgreSQL");
      properties.put("eclipselink.cache.shared.default", "true");
      properties.put("eclipselink.ddl-generation", "none");
      properties.put("eclipselink.logging.level.sql", "fine");
      properties.put("eclipselink.logging.parameters", "true");
      properties.put("eclipselink.deploy-on-startup", "true");
      properties.put("eclipselink.ddl-generation.output-mode", "database");
  }
  
  @Bean
  public JpaTransactionManager jpaTransMan(){
      JpaTransactionManager jtManager = new JpaTransactionManager(
              getEntityManagerFactoryBean().getObject());
      return jtManager;
  }
  
  @Bean
  public LocalEntityManagerFactoryBean getEntityManagerFactoryBean() {
      LocalEntityManagerFactoryBean lemfb = new LocalEntityManagerFactoryBean();
      lemfb.setJpaPropertyMap(properties);
      lemfb.setPersistenceUnitName(Vedantas.PU_NAME);
      lemfb.setPersistenceProviderClass(org.eclipse.persistence.jpa.PersistenceProvider.class);
      return lemfb;
  }
  }
  </code></pre>
  
  <p>Now, this works well. On startup, application config class is being loaded FIRST so "PropertySourcesPlaceholderConfigurer" gets registered and I can use @Value(...) annotations in jpa config class which gets loaded as SECOND.</p>
  
  <p>Today I have decided that I'll replace Eclipselink with Hibernate because of it's auditing abilities.</p>
  
  <p>To pom.xml I have added:</p>
  
  <pre><code>&lt;dependency&gt;
          &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
          &lt;artifactId&gt;hibernate-core&lt;/artifactId&gt;
          &lt;version&gt;5.2.9.Final&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.hibernate.javax.persistence&lt;/groupId&gt;
          &lt;artifactId&gt;hibernate-jpa-2.1-api&lt;/artifactId&gt;
          &lt;version&gt;1.0.0.Final&lt;/version&gt;
      &lt;/dependency&gt;
  
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
          &lt;artifactId&gt;hibernate-envers&lt;/artifactId&gt;
          &lt;version&gt;5.2.9.Final&lt;/version&gt;
      &lt;/dependency&gt;
  </code></pre>
  
  <p>and have changed jpa config class to:</p>
  
  <pre><code>@Configuration
  @EnableTransactionManagement
  public class JPAConfig {
  
  private Map&lt;String, String&gt; properties;
  
  @Value("${db.url}")
  private String dbConnectionURL;
  
  @Value("${db.user}")
  private String dbUser;
  
  @Value("${db.pass}")
  private String dbPassword;
  
  @PostConstruct
  public void init() {
      properties = new HashMap&lt;&gt;();
      properties.put("javax.persistence.jdbc.url", dbConnectionURL);
      properties.put("javax.persistence.jdbc.user", dbUser);
      properties.put("javax.persistence.jdbc.password", dbPassword);
      properties.put("javax.persistence.jdbc.driver", "org.postgresql.Driver");
      properties.put("javax.persistence.target-database", "PostgreSQL");
      properties.put("hibernate.hbm2ddl.auto", "create");
      properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
  }
  
  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(emf);
  
      return transactionManager;
  }
  
  @Bean
  public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
  }
  
  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setPackagesToScan(new String[]{"com.nws.vedica.model"});
      em.setPersistenceUnitName(Vedantas.PU_NAME);
  
      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
      em.setJpaPropertyMap(properties);
  
      return em;
  }
  }
  </code></pre>
  
  <p>Now, to my surprise, load/execution order of application config and jpa config classes has swapped so jpa config is being loaded FIRST and then application config SECONDLY which causes "PropertySourcesPlaceholderConfigurer" not being registered at jpa config class load time, so @value annotations are not working!</p>
  
  <p>I am really interested in knowing why is that so? Why has the execution order swapped?</p>
  
  <p>I know I can trick it by not declaring jpa config calass as @Configuration and just register it as a bean in application config class like:</p>
  
  <pre><code>    @Bean
      public JPAConfig setUpJpaHibernate() {
          return new JPAConfig();
      }
  </code></pre>
  
  <p>But still, I would like to know, what is happening here?</p>