Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a Spring Boot property with an underscore in its name via Environment Variables?

I want to set hibernate.format_sql in a Spring Boot app. I want to set it using environment variables.

Spring Boot rather handily converts all environment variables from, for example, FOO_BAR_BAZ to properties called foo.bar.baz inside the Spring context.

How can I set a property that has an underscore in the target name, in Spring Boot, using environment variables? Presumably HIBERNATE_FORMAT_SQL will be translated to hibernate.format.sql?

like image 438
EngineerBetter_DJ Avatar asked Dec 09 '15 12:12

EngineerBetter_DJ


People also ask

How do I set environment specific properties in spring boot?

Environment-Specific Properties File. If we need to target different environments, there's a built-in mechanism for that in Boot. We can simply define an application-environment. properties file in the src/main/resources directory, and then set a Spring profile with the same environment name.

How can we read properties file in spring boot using environment?

Using the Environment Object Another method to access values defined in Spring Boot is by autowiring the Environment object and calling the getProperty() method to access the value of a property file.

What is @configuration in spring boot?

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

How do I set different environments in spring boot?

Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration.


1 Answers

This is an old question but I'll answer it in case somebody else (like me) ends up here looking for this information.

HIBERNATE_FORMAT_SQL should do the trick

Actually it is not the OS environment variable that is "translated" but rather the Spring property name that is.

The name is translated in several ways and looked up against available environment variables. E.g. "hibernate.format.sql" is looked up as:

  1. hibernate.format.sql (as is)
  2. hibernate_format_sql (dots replaced with underscores)
  3. hibernate_format_sql (dashes replaced with underscores, the same in your case)
  4. hibernate_format_sql (dashes & dots replaced with underscores, the same in your case)

Then the same with UPPERCASE:

  1. HIBERNATE.FORMAT.SQL (as is)
  2. HIBERNATE_FORMAT_SQL (dots replaced with underscores)
  3. HIBERNATE_FORMAT_SQL (dashes replaced with underscores, the same again)
  4. HIBERNATE_FORMAT_SQL (dashes & dots replaced with underscores, the same again)

Although you cannot set an environment variable with a dot in the name with the set or export commands it is however possible with the env command. I defer judgement whether this is a good idea or not:

env "my.dotted.name=\"a value\"" the-command-you-want-to-run

Have a look at SystemEnvironmentPropertySource.java for details. I link to a specific version but you should make sure to look at the version you are using.

To troubleshoot these kinds of problems in a production environment you could try turning on debug logging for the property resolving code:

logging:
  level:
    org.springframework.core.env: DEBUG

... or by setting the appropriate environment variable :)

Edit: I highly recommend being familiar with the relevant Spring Boot documentation topic: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config

For the more tricky examples in the comments here, e.g. spring.jpa.properties.hibernate.criteria.literal_handling_mode, there might be different solutions available depending on how you launch you application.

You could set the variable as JSON, embedded in an environment variable.

env SPRING_APPLICATION_JSON='{"spring":{"jpa":{"properties":{"hibernate":{"criteria":{"literal_handling_mode":"BIND"}}}}}}' ./gradlew bootRun

Simply setting the variable as is might work also:

env spring.jpa.properties.hibernate.criteria.literal_handling_mode=BIND ./gradlew bootRun

Both of the above worked in my setup in so far as I was able to get the value in the running Spring Boot application this way:

@Value("${spring.jpa.properties.hibernate.criteria.literal_handling_mode}")
private String testSettingThroughEnvVariable;

Hope this helps! YMMV

like image 73
Max Avatar answered Oct 17 '22 11:10

Max