spring-boot property injection not workin in custom @Configuration class

By : Dodge
Source: Stackoverflow.com
Question!

i wanted to make a DatabaseConfig class to setup my database related stuff (EntityManager, DataSource, TransactionManager) and to get the properties i use @Value("${property.name}") on String fields

like

@Configuration
public class DataBaseConfig {
    @Value("${hibernate.connection.username}")
    private String hibernateConnectionUsername;
    @Value("${hibernate.connection.password}")
    private String hibernateConnectionPassword;
    @Value("${hibernate.connection.driver_class}")
    private String hibernateConnectionDriverClass;
    @Value("${hibernate.connection.url}")
    private String hibernateConnectionUrl;
    @Value("${hibernate.dialect}")
    private String hibernateDialect;
    @Value("${hibernate.showSql}")
    private String hibernateShowSql;
    @Value("${hibernate.generateDdl}")
    private String hibernateGenerateDdl;

// All my @Beans
}

The Problem is, that all those Strings are NULL instead of the values of my properties file.

if i put the code into my Application class (the one that has the main and is refernced in SpringApplication.run(Application.class, args);) the value injection works

In short, @Value works in my Application class, but not in my custom @Configuration classes :(

Anyone got an idea what could be wrong? Or are more inforamtions needed?

Thanks in advance

UPDATE: More code

Way 1, DB Config and @Value in my Application.java works with and without the PropertySourcesPlaceholderConfigurer

import java.beans.PropertyVetoException;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import com.mchange.v2.c3p0.ComboPooledDataSource;

@Configuration
@ComponentScan
@EnableJpaRepositories
@EnableAutoConfiguration(exclude = HibernateJpaAutoConfiguration.class)
public class Application {
    public static void main(String[] args) throws Throwable {
        SpringApplication.run(Application.class, args);
    }

    // @Bean
    // public static PropertySourcesPlaceholderConfigurer properties() {
    // PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
    // pspc.setLocations(new Resource[] { new ClassPathResource("application.properties") });
    // return pspc;
    // }

    /*****************************/
    @Value("${hibernate.connection.username}")
    private String hibernateConnectionUsername;

    @Value("${hibernate.connection.password}")
    private String hibernateConnectionPassword;

    @Value("${hibernate.connection.driver_class}")
    private String hibernateConnectionDriverClass;

    @Value("${hibernate.connection.url}")
    private String hibernateConnectionUrl;

    @Value("${hibernate.dialect}")
    private String hibernateDialect;
    @Value("${hibernate.showSql}")
    private String hibernateShowSql;
    @Value("${hibernate.generateDdl}")
    private String hibernateGenerateDdl;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setDatabasePlatform(hibernateDialect);
        boolean generateDdl = Boolean.parseBoolean(hibernateGenerateDdl);
        boolean showSql = Boolean.parseBoolean(hibernateShowSql);
        vendorAdapter.setGenerateDdl(generateDdl);
        vendorAdapter.setShowSql(showSql);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setDataSource(dataSource());
        factory.setPackagesToScan("xxx");

        return factory;
    }

    @Bean
    public DataSource dataSource() {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(hibernateConnectionUsername);
        dataSource.setPassword(hibernateConnectionPassword);
        try {
            dataSource.setDriverClass(hibernateConnectionDriverClass);
        } catch (PropertyVetoException e) {
            throw new IllegalArgumentException("Wrong driver class");
        }

        dataSource.setJdbcUrl(hibernateConnectionUrl);
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

Way 2 (what i want to have), DB Stuff in its own file (DatabaseConfing.java) does not work regardles of where i have the PropertySourcesPlaceholderConfigurer (Application or DatabaseConfig) as it is always called AFTER the @Beans inside the DatabaseConfig :(

import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import com.mchange.v2.c3p0.ComboPooledDataSource;


@Configuration
public class DatabaseConfig {
    @Value("${hibernate.connection.username}")
    private String hibernateConnectionUsername;
    @Value("${hibernate.connection.password}")
    private String hibernateConnectionPassword;
    @Value("${hibernate.connection.driver_class}")
    private String hibernateConnectionDriverClass;
    @Value("${hibernate.connection.url}")
    private String hibernateConnectionUrl;
    @Value("${hibernate.dialect")
    private String hibernateDialect;
    @Value("${hibernate.showSql}")
    private String hibernateShowSql;
    @Value("${hibernate.generateDdl}")
    private String hibernateGenerateDdl;

        // @Bean
        // public static PropertySourcesPlaceholderConfigurer properties() {
        // PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
        // pspc.setLocations(new Resource[] { new ClassPathResource("application.properties") });
        // return pspc;
        // }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setDatabasePlatform(hibernateDialect);
        boolean generateDdl = Boolean.parseBoolean(hibernateGenerateDdl);
        boolean showSql = Boolean.parseBoolean(hibernateShowSql);
        vendorAdapter.setGenerateDdl(generateDdl);
        vendorAdapter.setShowSql(showSql);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setDataSource(dataSource());
        factory.setPackagesToScan("xxx");

        return factory;
    }

    @Bean
    public DataSource dataSource() {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(hibernateConnectionUsername);
        dataSource.setPassword(hibernateConnectionPassword);
        try {
            dataSource.setDriverClass(hibernateConnectionDriverClass);
        } catch (PropertyVetoException e) {
            throw new IllegalArgumentException("Wrong driver class");
        }
        System.err.println(hibernateConnectionUrl);
        dataSource.setJdbcUrl(hibernateConnectionUrl);
        return dataSource;
    }
}
By : Dodge


Answers
@Import({ CacheConfig.class, DatabaseConfig.class })
@ComponentScan(excludeFilters = @Filter(Configuration.class))

did the trick.

By : Dodge


This video can help you solving your question :)
By: admin