Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot ignores dashes in property names in YML files

I've run into a weird behavior of Spring Boot (3.1.3) when using - in property names. Here's the sample code:

@SpringBootApplication
public class DemoApplication {
  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
}

@SpringBootTest
class DemoApplicationTests {
  @Value("${application.jokeurl}")
  private String jokeUrl;
  @Value("${application.joke-url}")
  private String jokeDashUrl;

  @Test
  void contextLoads() {
      System.out.println(jokeUrl);
      System.out.println(jokeDashUrl);
  }
}

And here's my application.yml:

application:
  joke-url: url1 #pay attention to dash in property name

When I run the test it prints two lines into the console:

url1
url1

We see that Spring injects the same String into Values referencing in fact different properties, i.e. @Value("${application.jokeurl}") and @Value("${application.joke-url}").

Now if I add one more property into application.yml as

application:
  joke-url: url1 #pay attention to dash in property name
  jokeurl:  url2 #no dash in property name

the same test prints different lines:

url2
url2

Now we see that the property application.joke-url is ignored in favor of application.jokeurl and again injects the same String into Values referencing different properties.

So my question is whether this is a bug or expected behavior?

like image 612
Sergey Tsypanov Avatar asked Jan 21 '26 22:01

Sergey Tsypanov


1 Answers

Spring Boot follows the concept of Relaxed Binding. The concept states:

Simple properties are bound by removing any special characters and converting to lowercase.

In your case, application.joke-url property via Relaxed Binding becomes application.jokeurl. The value of joke-url property is replaced by jokeurl property because they are same property as per that concept.

That's why you are facing the issue.

FYI: Spring Boot will not throw any warnings/errors as this is an expected behavior.


Solution:

The trick is not use any special characters for simple properties.

Use camelcase. Change jokeurl to jokeUrl to fix your issue.

application.yml or application.yaml:

application:
  joke-url: url1
  jokeUrl:  url2

Updated DemoApplicationTests:

@SpringBootTest
class DemoApplicationTests {
  
  @Value("${application.jokeUrl}")
  private String jokeUrl;

  @Value("${application.joke-url}")
  private String jokeDashUrl;

  @Test
  void contextLoads() {
      System.out.println(jokeUrl);
      System.out.println(jokeDashUrl);
  }
}

Output :

url2
url1

Tested with JDK 21 and Spring Boot 3.1.4. It's working.

like image 175
Anish B. Avatar answered Jan 24 '26 12:01

Anish B.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!