Search code examples
javaspringspring-bootconfigurationproperty

Spring boot @ConfigurationProperties not loaded


As the title says, I'm trying to use Typesafe Configuration Properties to load a list of DataSourceConfig objects. I have lombok for setter/getters

The main application class annotations

@Slf4j
@SpringBootApplication
@EnableConfigurationProperties
public class Application {

The configuration pojo

@Data
public class DataSourceConfig {
    private String key;
    private String dbname;
    private String dbpath;
}

The yml file

tenantdb:
    dataSourceConfig:
        -
            key: default 
            dbpath: file:eventstore/jdbc/database
            dbname: defaultdb
        -
            key: other
            dbpath: file:eventstore/jdbc/other
            dbname: dslfjsdf

Finally, the Spring Configuration class with the @ConfigurationProperties annotation.

@Configuration
@Profile("hsqldb")
@ImportResource(value = { "persistence-config.xml" })
@Slf4j
@ConfigurationProperties(prefix="tenantdb", locations={"datasources.yml"})
public class HsqlConfiguration {


    private List<DataSourceConfig> dataSourceConfig = new ArrayList<>();

    @Bean
    public List<DataSourceConfig> getDataSourceConfig() {
        return dataSourceConfig;
    }

With the config above, I get:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hsqlConfiguration': Could not bind properties to [unknown] (target=tenantdb, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is java.lang.NullPointerException
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:303)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:250)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initia

I've tried various combinations. If I change the annotation to @ConfigurationProperties(prefix="tenantdb.dataSourceConfig"), I don't get the error but List<DataSourceConfig> is empty.

HELP!!


Solution

  • You should use configuration properties as simple POJO with only getters and setters and have separate HsqlConfiguration which has this properties injected.

    Something like this:

    @Component
    @ConfigurationProperties(prefix="tenantdb", locations={"datasources.yml"})
    public class TenantDbProperties {
    
      //DataSourceConfig is POJO with key, dbpath and dbname
      private List<DataSourceConfig> dataSourceConfigs;       
    
      public List<DataSourceConfig> getDataSourceConfigs(){
          return dataSourceConfigs;
      }
    
      public void setDataSourceConfigs(List<DataSourceConfig> dataSourceConfigs){
          this.dataSourceConfigs = dataSourceConfigs;
      }
    }
    

    And in separate class have this properties injected as:

    @Configuration
    @Profile("hsqldb")
    @ImportResource(value = { "persistence-config.xml" })
    @Slf4j
    public class HsqlConfiguration {
    
        @Autowired
        private TenantDbProperties tenantDbProperties;
    
        //code goes here where you can use tenantDbProperties.getDataSourceConfigs()
    }