14

In a Spring Boot application, I want to use @ConfigurationProperties annotation with the same prefix to configure my two data sources depending to the profile. Why is it forbidden by Spring Boot Configuration Processor ? The error reported by gradle is:

...
:compileJava ... error: Duplicate `@ConfigurationProperties` definition for prefix 'spring.datasource'

Notes:

  • "Run As->Spring Boot App" works in STS
  • Without spring-boot-configuration-processor dependency, gradle build works (but the warning When using @ConfigurationProperties it is recommended to add 'spring-boot-configuration-processor' to your classpath to generate configuration metadata appears)

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.6.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

repositories {
    mavenCentral()
    maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile 'org.springframework.boot:spring-boot-configuration-processor:1.5.4.RELEASE'
    compile("com.h2database:h2")
}

application.properties

spring.datasource.driverClassName = org.h2.Driver
spring.datasource.username = sa
spring.datasource.password = sa

hello.Application

@SpringBootApplication
public class Application {

    public static void main(final String[] args) {
        final SpringApplication app = new SpringApplication(Application.class);
        app.setAdditionalProfiles("prod");
        app.run();
    }

    @Bean
    @Profile("dev")
    @ConfigurationProperties("spring.datasource")
    public DataSource dataSourceDev() {
        return DataSourceBuilder
                .create()
                .url(generateDevUrl())
                .build();
    }

    @Bean
    @Profile("prod")
    @ConfigurationProperties("spring.datasource")
    public DataSource dataSourceProd() {
        return DataSourceBuilder
                .create()
                .url(generateProdUrl())
                .build();
    }

}

Thanks in advance

cmaulini
  • 401
  • 1
  • 5
  • 9
  • Those beans are exactly the same why would you even needs that configuration?! – M. Deinum Aug 18 '17 at 15:12
  • My production code is more complicated. I have simplified it too much. I just updated my sample code. – cmaulini Aug 18 '17 at 15:33
  • Nonetheless still looks like you are doing things you shouldn't be doing. Why do you need this? The main issue, imho, is that you have different methods to generate a URL. But that is something you shouldn't have in code but in config. – M. Deinum Aug 18 '17 at 15:34
  • I'm having same issue.. this kind of setup works using intelij but as soon as I tried to compile with gradle it throws an error. "error: Duplicate ..." do you have a solution? – Cyrill Zadra Aug 02 '18 at 14:29

1 Answers1

1

I think you are confused on how this works. The code should mostly stay the same. The properties change when you define which profile to load at start up.

application-dev.properties

spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.url=

appilication-prod.properties

spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.url=

And only one bean setup the datasource.

DJDaveMark
  • 2,669
  • 23
  • 35
ndrone
  • 3,524
  • 2
  • 23
  • 37
  • 1
    OK for the data source, it was not a good example. My question is more general: I want to create multiple beans that have some commons properties defined in `application.properties`, some profile specifics properties defined in `application-.properties` and some "runtime properties" that must be programmed. I want to use `@ConfigurationProperties` to handle commons and profile specifics properties (to avoid having multiple `@Value` tags and `setProp()`in my `@Configuration` class. – cmaulini Aug 21 '17 at 07:05