Question

I am running into some configuration issue since trying to switch to javaconfig from xml config.

Here is the problematic configuration class:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@Profile({ "default", "cloud" })
public class DataConfiguration {

    @Value("${database.driverClassName}")
    private String driverClassName;

    @Value("${database.url}")
    private String url;

    @Value("${database.username}")
    private String username;

    @Value("${database.password}")
    private String password;

    @Value("${database.validationQuery}")
    private String validationQuery;

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setTestOnBorrow(Boolean.TRUE);
        dataSource.setTestOnReturn(Boolean.TRUE);
        dataSource.setTestWhileIdle(Boolean.TRUE);
        dataSource.setTimeBetweenEvictionRunsMillis(1800000);
        dataSource.setNumTestsPerEvictionRun(3);
        dataSource.setMinEvictableIdleTimeMillis(1800000);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setMaxActive(5);
        dataSource.setLogAbandoned(Boolean.TRUE);
        dataSource.setRemoveAbandoned(Boolean.TRUE);
        dataSource.setRemoveAbandonedTimeout(10);
        return dataSource;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory());
        return transactionManager;
    }

    @Bean
    public HibernateJpaVendorAdapter jpaVendorAdapter() {
        return new HibernateJpaVendorAdapter();
    }

    @Bean
    public HibernatePersistence persistenceProvider() {
        return new HibernatePersistence();
    }

    @Bean(name = "entityManagerFactory", destroyMethod = "close")
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setPackagesToScan("com.bignibou.domain");
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPersistenceProvider(persistenceProvider());
        entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
        entityManagerFactoryBean.setJpaPropertyMap(propertiesMap());
        return entityManagerFactoryBean.getObject();
    }

    public Map<String, String> propertiesMap() {
        Map<String, String> propertiesMap = new HashMap<>();
        propertiesMap.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        propertiesMap.put("hibernate.hbm2ddl.auto", "update");
        propertiesMap.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
        propertiesMap.put("hibernate.connection.charSet", "UTF-8");
        propertiesMap.put("hibernate.show_sql", "true");
        propertiesMap.put("hibernate.format_sql", "true");
        propertiesMap.put("hibernate.use_sql_comments", "true");
        return propertiesMap;
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }

}

Here is the exception I get:

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public static javax.persistence.EntityManager org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(javax.persistence.EntityManagerFactory)] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:181)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
    ... 121 more
Caused by: java.lang.NullPointerException
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.initProxyClassLoader(SharedEntityManagerCreator.java:151)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.<init>(SharedEntityManagerCreator.java:143)
    at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:118)
    at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:96)
    at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:64)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
    ... 122 more

It seems there's an issue with the entityManagerFactory config... What I am getting wrong?

Was it helpful?

Solution

If you are not using the entityManagerFactory() method anywhere in your java configuration, you can instead return the LocalContainerEntityManagerFactoryBean object.

The LocalContainerEntityManagerFactoryBean is both an InitializingBean and a FactoryBean. These are special interfaces that Spring can use to initialize a bean and then add it to the context.

You could therefore change your method to

@Bean(name = "entityManagerFactory", destroyMethod = "close")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setPackagesToScan("com.bignibou.domain");
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPersistenceProvider(persistenceProvider());
    entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
    entityManagerFactoryBean.setJpaPropertyMap(propertiesMap());
    return entityManagerFactoryBean;
}

Spring will take care of calling afterPropertiesSet() and getObject() on the object returned by the method and adding the created EntityManagerFactory bean to the context.

This is detailed in the IoC chapter of the Spring documentation.

OTHER TIPS

adding the following line sorted the issue:

entityManagerFactoryBean.setJpaPropertyMap(propertiesMap());
entityManagerFactoryBean.afterPropertiesSet();//NOTICE HERE!!!
return entityManagerFactoryBean.getObject();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top