spring boot .env variables in application.properties - spring-boot

I have created .env file where I keep variables now I want them to be defined in my application.properties but this is not working. What do I need to add to get the variables.
.env file
MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=root
application.properties
spring.profiles.active = dev
application-dev.properties
# mysql database properties
spring.datasource.url = jdbc:mysql://localhost:3306/testdb?useUnicode=true&serverTimezone=UTC&server&createDatabaseIfNotExist=true
spring.datasource.username = ${MYSQLDB_USER}
spring.datasource.password = ${MYSQLDB_ROOT_PASSWORD}
# hibernate properties
spring.jpa.hibernate.ddl-auto = create
spring.jpa.show-sql = true

This won't happen automatically. You can make it work by adding this to your application-dev.properties:
spring.config.import=optional:file:.env[.properties]
Another option is to use an additional library that adds support for this, such as https://github.com/paulschwarz/spring-dotenv.
There is some discussion about adding support for this in Spring Boot, but it is not a high priority.

Related

Un-set a property by overriding it

I have a logistical Problem with spring property files. Im doing a refactor of our profiles with the following goal:
I want to have two configurations in which I want to start the application. One for local development and one for the production environment. I know the property values for both configurations. The aim is to have the default profile act as the local configuration and have just one profile 'production' which will overwrite values for the production scenario.
The problem is now that the local configuration sets some properties which the production config does not set. So in any case where the production config is an extension of the local (i.e. default) config, there will be some properties which are set to some value which should actually be undefined.
Is there some way by which I can "un-set" these properties in the production profile?
Example of how I would like it to work:
# application.properties
# this is the local configuration
app.config.name = "FOO"
services.search.url = localhost:8081
app.mock.provider = localhost:8082
.
# application-production.properties
# activating this should yield the production configuration
services.search.url = production-search-url.com # Overriding works of course
app.mock.provider = PLEASE_MAKE_THIS_PROP_UNDEFINED_AGAIN # I suppose this doesn't work
spring.sentry.dns = nw9x74b3kqllanx6rh3
# app.config.name = "FOO" should be and is still set

application-profile.yml does not pickup properties from main application.yml

I have a Spring boot application with different environments. I have a main application.yml with a set of properties and an application-test.yml for my test environment.
Inside my application.yml, I have the following config
spring:
liquibase:
enabled: false
user: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
change-log: classpath:db/changelog-master.yaml
And inside my application-test.yml, I have the following
spring
liquibase:
user: sa
password: password
I was expecting my test environment to use liquibase.user and liquibase.password from the application-test.yml and pick the two other sub-properties (liquibase.enabled and liquibase.change-log) from application.yml. My reasoning was that in my test environment, the Application context would pick up all the properties in application.yml and then overwrite only the subkeys defined in application-test.yml, while keeping the original values of application.yml if not explicitly overwritten.
But that does not seem to be the case; it looks as if the key liquibase in my application-test.yml overwrites all the key and subkeys of the liquibase defined in application.yml.
Therefore since in my application-test.yml, liquibase.enabled and liquibase.change-log are not defined; the test environment does not know about these values. I was expecting them to be picked up from the main application.yml instead. I tried to define them manually in my application-test.yml and my tests work fine. If I remove them, my tests fail because they use the default properties for liquibase instead of liquibase.enabled: false and liquibase.change-log: classpath:db/changelog-master.yaml
What I would like to do is the following:
In my main application.yml, have
main_key:
sub_key_1: value_1
sub_key_2: value_2
sub_key_3: value_3
And in my application-test.yml, have only
main_key:
sub_key_1: test_value_1
have my test environment pickup sub_key_2: value_2 and sub_key_3: value_3 directly from application.yml, without them being overwritten by nothing in my test environment (since they are not defined in my application-test.yml)
Is it possible to have think kind of logic : if main_key.sub_key_2 is defined in application-test.yml is defined, then use it, otherwise use the main_key.sub_key_2 defined in application.yml ?
I feel that if I don't define all the sub_keys of my main_key in my application-test.yml, it is not possible to do it.
Many thanks for your help
Actually, I think I know why it does not work.
I had an empty application.yml inside my test/resources/application.yml. So I believe spring boot picks up the test/resources/application.yml instead of the src/main/resources/application.yml when test/resources/application.yml exists.
Which explains why the properties in my src/main/resources/application.yml were not picked up at all.
The solution was simply to delete the test/resources/application.yml

Spring Application.Properties and Application-dev.properties files parameter conflict

profile logic in my application.properties file.My problem is when I use -dev ,it reads value from application-dev.properties.But I have same key which does not exist in my application-dev.properties but exist on application.properties,spring continue to read values from application.properties
application.properties
myfirstkey=x
mysecondkey=x
application-dev.properties
mysecondkey=dev
-Dspring.profiles.active=dev (// I pass profile value and see result by the way)
Output mysecondkey dev ,it is okay no problem
Output myfirstkey is x (my expectation is empty),but it doesnt exist in application-dev.properties?Is there anyway to prevent application.properties read
Well, application.properties are basically your 'default' .properties and you can't just (on a case-per-case basis) disable them, so the fix would be to do this in your -dev.properties.
myfirstkey=

Adding Environmental Variables to application.properties Spring Boot application

I need to externalize the parameters set in my application.properties using environmental variables.
This is my application.properties file:
spring.datasource.url= jdbc:mysql://${MYSQL_URL}:${MYSQL_PORT}/${MYSQL_DBNAME}
spring.datasource.username= ${MYSQL_USERNAME}
spring.datasource.password= ${MYSQL_PASSWORD}
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto= update
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect
And those ${---} are Environmental Variables.
But when I try to run my application I get this error:
Property: spring.datasource.url
Value: jdbc:mysql://${MYSQL_URL}:${MYSQL_PORT}/${MYSQL_DBNAME}
Origin: class path resource [application.properties]:1:24
Reason: Could not resolve placeholder 'MYSQL_URL' in value "jdbc:mysql://${MYSQL_URL}:${MYSQL_PORT}/${MYSQL_DBNAME}"
I found that the environment variables were defined after I launched Eclipse, and Eclipse did not recognize them, so the solution was simple: restarting Eclipse.

Unable to detect database type

I'm trying to create a Spring Boot application using sqljdbc4 driver with this config:
spring:
datasource:
url: "jdbc:sqlserver://dbhost:1433;databaseName=test"
username: dbuser
password: dbuser
tomcat:
test-on-borrow: true
validation-query: select 1
But, when I run, I get this error: Unable to detect database type
I was debugging BatchDatabaseInitializer, where error came from, and when it calls JdbcUtils.commonDatabaseName(...), "Microsoft SQL Server" is returned as product name that doesn't match with any DatabaseDriver's product name.
I tried other drivers but they all have the same problem.
Is it a bug?
I'm using Spring Boot 1.5.1-RELEASE.
You need to properly configure your spring.datasource config in application.properties file if you're using spring-batch to create batch jobs. Below is mine ->
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/batch_repo
spring.datasource.username=batch_username
spring.datasource.password=batch_password
spring.datasource.platform=mysql
spring.batch.initialize-schema=always
spring.batch.initialize-schema when configured to "always", will create the necessary spring batch related tables in your schema.
Alternatively, if you assign it to "never", it will refrain from creating the tables. In both these cases your error should get resolved.
Try spring.batch.jdbc.initialize-schema=never in props file. It worked for me in spring-boot v2.6.x
Add this in your Application file within the main function.
#SpringBootApplication(
exclude = {
BatchAutoConfiguration.class,
JmxAutoConfiguration.class
},
excludeName = {
"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration",
}
)
Put this in your application.properties.
spring.batch.schema=classpath:org/springframework/batch/core/schema-sqlserver.sql
Check your application.properties file like below.
Note: springbatch is my DB name
spring.datasource.url=jdbc:mysql://localhost:3306/springbatch
spring.datasource.username=root
spring.datasource.password=Vishal#123
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.batch.jdbc.initialize-schema=always

Resources