3

I am using @ConfigurationProperties

@Getter
@Setter
@ConfigurationProperties(prefix = "my")
@Component
public class MyProperties {
    private Nested single;
    private List<Nested> many;
}

@Getter
@Setter
public class Nested {
    private String foo;
    private String bar;
}

test.properties

my.single.foo=A
my.single.bar=B
my.many[0].foo=C
my.many[0].bar=D

I am running test with the following configuration:

@TestPropertySource(locations = "classpath:test.properties",
    properties = {
            "my.single.bar=bb",
            "my.many[0].bar=dd"
    })

The problem is that I get my.many[0].foo=null because as I understood Spring completely replaces first element in list with {foo: null, bar: "dd"}

Please help.

sinedsem
  • 5,413
  • 7
  • 29
  • 46
  • actually everyone is struggling with "arrays in properties file", because there's no word about "arrays" in `java.util.Properties` ...but spring seems to have work around. But still, I would not regard it as "defect", since `properties` is documented to have the highest precedence, and(they could argument) you (sort of) set `my.many[0].*=null` ... the fix is straightforward: provide `my.many[0].foo`, but of course nasty if you have "rich" properties ...is XML or YAML a feasible approach/try-out for you? – xerx593 Jan 15 '20 at 20:53
  • @xerx593 Are you saying this will work if I change my properties file to YAML? – sinedsem Jan 16 '20 at 07:20
  • no, i don't say "will" ...i'd say "it is worth trying" ...and i (still) would prefer xml to yaml. but if the "defect" still exists with xml or yaml, then it is clearly a defect (, because these allow finer grained data structures...) – xerx593 Jan 16 '20 at 11:43
  • @xerx593 Ij ust tried with YAML. Doesn't work either. I also noticed that not only single element in array is erased, but all array elements are removed. – sinedsem Jan 16 '20 at 12:58

1 Answers1

1

I fought with this a lot, and found a reasonable workaround, so I thought I'd share it here.

Using Spring's capability of combining properties, as described here: Spring properties that depend on other properties, I've done this:

Original application.properties:

my.list[0].x = x0
my.list[0].y = y0
my.list[1].x = x1
my.list[1].y = y1

application.properties that allows overriding x0 externally:

overridable.property = x0
my.list[0].x = {overridable.property}
my.list[0].y = y0
my.list[1].x = x1
my.list[1].y = y1

and now -Doverridable.property=xxx replaces just what I need

Idotzang
  • 269
  • 2
  • 6