spring:
profiles: dev
spring.datasource:
driver-class-name:
password: ~
url: ~
username: ~
---
secdb:
profiles: dev
spring.datasource:
driver-class-name: ~
password: ~
url: ~
username: ~
---
I have above two properties declared as shown in the application.yml file but when I use it in implementation class as follows.
#Value("${spring.datasource.url}")
private String URL;
it works and picks up the url from YML file.
but when I do as follows
#Value("${secdb.spring.datasource.url}")
private String URL;
it fails at spring boot start saying
Could not resolve placeholder 'secdb.spring.datasource.url' in value...
As, I am at beginner level. YML may be wrong but my intention is to have two data sources in the YML file and use the second one for one JDBC connection other one is default. Please, guide me through the mistake
You have made two mistakes in your yaml file.
Don't use space before ---.
Before your first spring.datasource:, there is a space. It indicates spring.datasource: is a subproperty of spring:.
#Value("${secdb.spring.datasource.url}") is absolutely not the right way. Even you active secdb, you also need to get the value like #Value("${spring.datasource.url}").
I do't suggest you to use Spring profiles like secdb: profiles: dev. It's not a familiar way. You can use it like spring: profiles: secdb and active it just like spring.profiles.active=secdb. Or if you insist to use it that way, you need to active it like spring.profiles.active=secdb.
After all, if you want to use Spring profiles properties, you need to active it just like
$ java -jar -Dspring.profiles.active=production
or
add spring.profiles.active=production in application.properties.
I suggest you to read this document in detail.
I will be glad if it helps.
Related
I have a property with an array value that I want to override when a certain profile is active. But instead of replacing the property Spring Boot performs a strange merge of two arrays. It worked fine on Spring Boot version 1.5 but stopped after upgrading to version 2.5.
I have an application.yml that looks like this:
spring.config.use-legacy-processing: true
configuration:
type:
my-type:
... # some configuration properties
my-list: ['first','second','third']
---
spring:
profiles: dev
configuration:
type:
my-type:
... # some configuration properties
my-list: ['fourth']
I am retrieving this configuration as Map and for property my-list when running with dev profile I am getting an array ['fourth','second','third']. It is the default array with the first element replaced by the value from the profile configuration. If I would replace profile array with ['fourth','fifth'] then the result would be ['fourth','fifth','third'].
I tried to disable legacy processing and use spring.active.on-profile it still works the same way.
If I am consuming properties to class instead of Map then everything works fine but the list of properties is not fixed.
Maybe someone knows what could be done about this?
Currently I have consul configured to read a YML and load different properties as follows in bootstrap.yml:
spring:
cloud:
consul:
host: ${CONSUL_HOST}
port: ${CONSUL_PORT}
config:
format: YAML
acl-token: ${CONSUL_TOKEN}
default-context: application
prefix: config/
name: application
data-key: data/properties
This works correctly.
Now I have included another Key/Value in consul at the same level as "properties", which is as follows:
config/application/data/properties
config/application/data/newproperties
I am trying to be able to load both data keys at the same time so that I can keep the different settings separate, but I am not managing to properly configure bootstrap.yml for this to happen.
I've tried setting the type as FILES, but haven't gotten it to work.
Have any of you faced this problem before?
Thanks!
After investigating and debugging the consul key/value behavior, it seems that it is not possible to read two different keys simultaneously.
I am trying to set up in-memory H2 tables for a test class in my Spring boot application.
My config looks something like:
spring:
jpa:
show-sql: true
generate-ddl: true
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create-drop
datasource:
# not sure which one to use so added both just in case
initialization-mode: always
initialize: true
platform: h2
# casting a wide net here, but no cookie - completely ignored
data: data-h2.sql,classpath*:data-h2.sql, classpath:data-h2.sql
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
driver-class-name: org.h2.Driver
username: sa
password:
As you can see, I'm trying to load a data-h2.sql script upon db initialization.
Unfortunately, the property is ignored no matter the value.
I am certain the configuration file is being picked up properly (e.g. among others, I desperately added a #Value("${spring.datasource.data}" -annotated property in my test class and the value was indeed populated correctly).
As an alternative, I could annotate the test class with #Sql("classpath:data-h2.sql") which did run the script - however it did so for every test, while I wanted the script to be run once before any test execution.
I also tried removing that and using a blank schema.sql and moving the population to data.sql (as suggested here), but Spring would complain about the empty schema file - which is useless to me, because my schema is auto-generated and I certainly don't want to re-create it (NB: probably a conflict with a hibernate property if memory serves).
I've browsed some of the answers here, but the only one I could use, is not working.
The only solution I can see is to keep the #Sql annotation, but try and clear the tables after every test with another #Sql annotation launching another script on #After.
This seems insane to me - there must be a better solution.
Am I missing something more esoteric than it already is in my configuration?
Simply put your file in the /main/resources directory (what you already did)
Spring Boot 2:
The correct property is:
spring.datasource.initialization-mode=always
Read more about this topic in the Spring Boot Documentation: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-initialize-a-database-using-spring-jdbc
Spring Boot 1
You only have to place data-h2.sql in the classpath
Read more about this topic in the Spring Boot Documentation:
https://docs.spring.io/spring-boot/docs/1.5.8.RELEASE/reference/htmlsingle/#howto-initialize-a-database-using-spring-jdbc
My springboot application has a few yml files(each for various profiles - dev, prod) to load configurations from. I am moving the configurations to the DB.
Sample configurations are like,
admin:
id: user05
firstname: Brian
lastname: Leavy
purl: http://plixes.com/seai/ji
I have the values read from the DB and have it locally. I am not sure how to inject these values in my program onto these values, like key-value, as,
admin.id:user05
admin.firstname: Brian
admin.lastname: Leavy
admin.purl: http://plixes.com/seai/ji
so that they are available to the application as it would normally be.
I would need them to be initialized very early since some of the values are springboot configurations, like say,
server:
port: 5007
Any pointers would be really helpful.
EDIT1:
I just found out after hours of searching, that you could do something like this,
SpringApplication app = new SpringApplication(Lexon.class);
app.setDefaultProperties(Collections
.singletonMap("server.port", "5007"));
app.setDefaultProperties(Collections
.singletonMap("admin.id", "user05"));
This works, but does not look clean.
Is there a better way to do this?
There is Spring Boot Configuration library that can externalize the configuration to a database or a git repository.
With that, you add an data source and an SQL statement to retrieve the property values.
For example, on application.yml:
spring:
cloud:
config:
server:
jdbc:
sql: SELECT KEY, VALUE from MY_PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?
Check this site for more details: https://www.devglan.com/spring-cloud/jdbc-backend-spring-cloud-config
I am not sure if this is a valid question, but I was wondering if this was possible.
A Spring boot project has an application.properties and several profile specific properties. The profile specific properties overrides the defined application.properties with whatever has been defined in the application-profile.properties, and also adds those properties belonging exclusively in the profile specific properties. Illustration below:
application.properties
key1=value1
key2=value2
application-profile.properties
key1=valueProfile1
key3=valueProfile3
When the application starts with this profile, the final properties that it sees are as follows:
key1=valueProfile1
key2=value2
key3=valueProfile3
In short, you have a union of both the common and profile properties, with the profile property values appending and overriding the common.
But what if, in a god-knows-what scenario, i need a property to be defined in the common application.properties but i need it to be "undefined" when the application starts in one particular profile. Illustration below:
application.properties
keySpecial=specialValue
key1=value1
key2=value2
application-special.properties
key1=valueSpecial1
//unset or undefine keySpecial
keyAlternateSpecial=specialAlternateValue
key3=valueSpecial3
Now, when the application starts with this "special" profile, I want it to see the final properties as follows:
keyAlternateSpecial=specialAlternateValue
key1=valueSpecial1
key2=value2
key3=valueSpecial3
Note that keySpecial is not defined, doesnt even exist, when the application runs in this special profile.
Is this possible?
Note: I know that I can refrain from defining "keySpecial" in the common application.properties, and define them in all other profile specific properties. And specify "keyAlternateSpecial" only in "special" profile properties.
More Info:
The scenario that made me wonder about this is the spring boot datasource jndi property. From the docs
spring.datasource.jndi-name= # JNDI location of the datasource. Class, url, username & password are ignored when set.
The mere existence of this property makes the application ignore the other datasource properties (class,url,username,password) even if they are set.
I am not allowed to remove the jndi property from the "application.properties". But instead I wanted to unset/undefine it and add the other datasource properties (class,url,username,password) in a "special" profile properties.
You can fake removing spring.datasource.jndi-name from application.property by setting spring.datasource.jndi-name=false. This way #ConditionalOnProperty(prefix = "spring.datasource", name = "jndi-name") won't enable autoconfiguration class. For details look at ConditionalOnProperty javadoc.
I solved in my use case with by defining the JNDI property in default profile which is activated when no other profiles are defined, in this way during development I can use a different datasources without JNDI.
Here's an excerpt of my application.yml file, don't know if this works for you.
spring:
jpa:
database: POSTGRESQL
hibernate:
ddl-auto: none
# Default profile, active by default on JBoss since no spring profiles are activated
---
spring:
profiles: default
datasource:
jndi-name: java:jboss/datasources/anagraficaDS
# Development configuration
---
spring:
profiles: development
datasource:
platform: postgres
url: jdbc:postgresql://localhost:5432/my-db
username: root
password: secret
driverClassName: org.postgresql.Driver
Late to the party, but:
Since SpringBoot 2.4 a good option would be profile groups.
Put keySpecial=specialValue (and other related config) in its own profile - let's call it special.
Then add it to the profiles it needs to be in. So if you have profiles a, b, and c, and you only need special to be in a and b, then:
spring.profiles.group.profilea[0]=special
spring.profiles.group.profileb[0]=special