Grzegorz Poznachowski
Grzegorz Poznachowski

Reputation: 644

Spring Boot - merging map of map property

I'm using Spring Boot 1.5.6 and have configuration properties as follows:

@Component
@Getter
@Setter
@ConfigurationProperties("test")
public class TestProperties {
    private Map<Integer, Integer> map;
    private Map<String, Map<Integer, Integer>> mapOfMaps;
}

and two yaml configuration files:

application.yml

test:
  map:
    1: 10
    2: 20
  mapOfMaps:
    KEY1:
      1: 10
      2: 20
    KEY2:
      3: 30
      4: 40

application-dev.yml

test:
  map:
    100: 100
  mapOfMaps:
    KEY1:
      100: 100

When I ran my application with dev profile I expected that both properties would contain only dev profile values (so basically an exact match of application-dev.yml).

Sample project is available here: https://github.com/poznachowski/spring-boot-mapmerge

For a simple map property it worked fine, but for a mapOfMaps property it resolves to {KEY1={100=100}, KEY2={3=30, 4=40}}.

Does that behave by design? If yes, is there a way to make it work in a way I described?

Upvotes: 4

Views: 3227

Answers (1)

J.B.
J.B.

Reputation: 21

This is working as designed. The application.yml can be seen as providing the default values for other profiles to override.

Essentially the base configuration will get merged with the profile that you enable, but the keys in the active profile will supersede those of the default.

Spring Boot - Properties & configuration documentation

When I run your example with spring boot 1.5.6.RELEASE the resulting configuration object looks as follows:

test:
  map:
    1: 10
    2: 20
    100: 100
  mapOfMaps:
    KEY1:
      1:10
      2:20
      100:100
    KEY2:
      3: 30
      4: 40

If you wanted to have either the one or the other configuration active you would have to put the first in another application-{profile}.yml or make sure that you override every property in the default configuration.

Upvotes: 2

Related Questions