I have generated a spring boot project using jHipster. I want to reduce the number of connections to the database so I have modified the application-prod.yml file by adding the maximumPoolSize tag like this
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password:
maximumPoolSize: 2
But when I try deploying the application I have 10 connections to the database. What am I doing wrong?
Thanks
With Spring Boot 1.4 the general properties have been reduced and moved to specific properties per DataSource provider (which is also explained in the reference guide and the release notes).
So instead of using spring.datasource.maximumPoolSize you should be using spring.datasource.hikari.maximumPoolSize
For a list of properties see the appendix.
Related
Versions
Spring Parent: 2.7.4, Spring Cloud Version: 2021.0.4, Java Version: 11
Issue
My Spring service has been using Eureka to connect to the config server for a long time, but I want to upgrade to Spring 2.7.4. I understand that as of Spring 2.4, the bootstrap context has been deprecated (source) and I need to make some adjustments to the old bootstrap properties and move them over to application.properties.
The documentation for Spring Cloud specifies that in order for me to continue to use discovery-first config lookup, I need to define a spring.config.import property with an optional configserver entry (source). Since I'm also using Vault, I define the property as follows:
spring.config.import = optional:configserver:placeholder,vault://<my-generic-backend>/dev
Next, I need to define the following properties (source). These properties were already defined in my old bootstrap.properties, so all I need to do is copy and paste.
spring.cloud.config.discovery.enabled = true
spring.cloud.config.discovery.serviceId = config-server
eureka.client.serviceUrl.defaultZone = <my-eureka-url>
Unless I'm missing something, these are all the steps I need to take in order to upgrade to 2.7.4. However, when I run the Spring service, it complains that it can't find the config server (via Eureka, or via URL), then it registers successfully with Eureka, and then continues trying and failing to find the config server.
Here is some of the output of the program:
> Running with Spring Boot v2.7.4, Spring v5.3.23
> Could not locate configserver via discovery: No instances found of configserver (config-server)
> Could not locate PropertySource ([ConfigServerConfigDataResource#2aa6311a uris = array<String>['placeholder'], optional = true, profiles = list['local']]): Invalid URL: placeholder
...
> DiscoveryClient_<my-project-name>/local - registration status: 204
I understand why it's failing to find a config server at URL: placeholder since that's not a valid URL, but I don't understand how the service can successfully register with Eureka yet not be able to find the config server. I know the service is registered because the output of the program says it registered correctly (and I can see it in the registry), and I know that the config server has the correct entity ID (config-server) because it was copied and pasted from the old bootstrap (and I can see config-server in the registry).
Workaround with Hardcoded URL
When I hardcode the config server URL like this (and set spring.cloud.config.discovery.enabled to false), the config is loaded properly from the server:
spring.config.import=configserver:https://<my-hardcoded-config-url>.com,vault://<my-generic-backend>/dev
Workaround with Bootstrap
It's possible to return to using the bootstrap context and still use Spring 2.7.4 with discovery-first config lookup by adding the "spring-cloud-starter-bootstrap" dependency. So I added the dependency to my POM and moved these properties back to bootstrap.properties from application.properties.
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server
I moved the Vault and Eureka properties back into bootstrap.properties as well. The new application.properties now contains no values relating to Eureka, Vault, and Cloud Config.
When I run the service, it does indeed find the address for the config server through Eureka, as expected (although it fails to connect because it's the internal address and I'm running locally).
Conclusion
While these are valid workarounds, it's frustrating to not be able to have a dynamic URL for the config server (as is the entire point of using Eureka). Right now, it looks like my choices are either to use a hard-coded URL and risk having to change every property file, or use a deprecated behavior that Spring documentation specifically disfavors (source).
I would appreciate any guidance you have on the issue, and I thank you in advance.
As a developer, I use the default dev profile in my local development environment. Here is part of my application-dev.properties file:
# Profiles
spring.profiles.include=auth
Previously I used Spring Boot 2.3.0.RELEASE and the spring.profiles.include property included auth profile at runtime.
But after I migrated to Spring Boot 2.4.0, I don't get the auth profile enabled. spring.profiles.include property doesn't seem to work as before.
Please tell me how I can configure my profiles so that I get the same result as before migration. (I would not like to use profile groups here)
Thanks in advance!
In case your configuration processing has changed in incompatible ways and you wish to use the "legacy" processing way, you can re-enable it by setting:
spring.config.use-legacy-processing=true
or alternatively, using YAML:
spring:
config:
use-legacy-processing: true
which should revert the configuration processing to the 2.3.x equivalent. Do note, however, that this property exists solely to ease the migration of profile configurations from 2.3.x to 2.4.x and will likely be deprecated and removed in a future major release1, so you should still try to migrate ASAP. To understand the reason for this change and some additional information, read on.
Of note in 2.4.0 are the following two paradigms:
So in Spring Boot 2.4 we’re planning to make two significant changes to the way the properties and YAML files are loaded:
Documents will be loaded in the order that they’re defined.
Profiles can no longer be activated from profile specific documents.
This change has in fact made the what-overrides-what-when logic considerably simpler to digest, but leads to having to disable some functionality. For example:
my.prop: test
---
spring.profiles: prodprops
my.prop: prod
---
spring.profiles: prod
# no longer works - activating a profile from a profile-specific document!
spring.profiles.include: prodprops
would lead to an exception as the configuration attempts to activate a profile from a profile-specific document, which is not allowed anymore.
To cover this use case (and others), profile groups have been added as a feature. This means that to enable your previous behaviour, you would need to create a profile group as follows:
spring.profiles.group.<group>=dev, auth
or alternatively, in YAML:
spring:
profiles:
group:
<group>: dev, auth
Where <group> is the name of your chosen profile group. Note that you can define multiple groups, all of which should have different names. If you then start your application using the <group> profile, all the profiles that are part of that group should be activated.
As a side-note, Spring Boot 2.4.0 additionally added support for multi-document properties files, which look as follows:
test=value
spring.profiles.active=local
#---
spring.config.activate.on-profile=dev
test=overridden value
Note the document separator (#---). This allows you to have similar overriding logic in .properties files as in .yml files.
Again, this and other information is provided in the relevant update post.
1 If prior deprecations are any indicator, the property should be removed in 2.5.0 at the earliest or 2.6.0 at the latest, with the latter being more likely (and a deprecation as of 2.5.x).
You can use spring.config.import using classpath:
spring.config.import=classpath:application-DEV.yml,classpath:application-auth.yml
Although we have an accepted answer above. But I would share my solution via multiple files.
I'm having multiple config files in my project
./
application.yml
application-auth.yml
application-mockauth.yml
application-datasource.yml
The body of application-auth.yml or application-datasource.yml are the same as we're implementing before spring boot 2.4. Minor adjustment will be located inside application.yml
spring:
profiles:
group:
"dev": "datasource,mockauth"
"prod": "datasource,auth"
Instead of spring.profiles.include, you will group related config with environment name (dev, prod...).
You can also use spring.config.import to import configuration from other file according this documentation Config file processing in Spring Boot 2.4.
I am finding the following difficulties trying to configure Spring Data JPA into my Spring Boot project.
I have the following problem related to the application.properties file. This is my original application.properties file content:
spring:
application:
name: Spring Boot Excel API
datasource:
driverClassName: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3306/SOC_Dashboard
username: admin
password: password
timeBetweenEvictionRunsMillis: 1000
testWhileIdle: true
validationQuery: SELECT 1
in which I configured the database connection for my project (I used JdbcTemplate to interact with my databse since now and I am replacing with Spring Data JPA).
I am not so into Spring Boot but it seems to me that exist 2 ways to set the configuration into my application.properties file: one is as done in my configuration (using something like a tree structure) and another one use a "flast" structure.
Searching online I only found this "flat" configuration for JPA:
spring.jpa.hibernate.ddl-auto=none
that is not working in my case. Putting it into my application.properties file I obtain a syntax error due to the fact that it is using the other tree style.
So I am trying to change my original file in this way:
spring:
application:
name: Spring Boot Excel API
datasource:
driverClassName: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3306/SOC_Dashboard
username: admin
password: password
timeBetweenEvictionRunsMillis: 1000
testWhileIdle: true
validationQuery: SELECT 1
jpa:
hibernate:
ddl-auto: none
Is it the right way to proceed?
Another doubt is related to the ddl-auto configuration. My development is database driven. I design the DB tables and JPA entity have to map these tables. I don't want to create\modify tables starting from my entity. Is it the right configuration?
To answer your first question, YES. It is the right way of configuring spring.jpa.hibernate.ddl-auto configuration in YAML files. And the properties file which you've mention in YAML format. So, the file name should be application.yml. In spring boot, spring-boot-starter-web dependency will automatically include snakeyaml dependency to read YAML files.
For the second question, you can mention none for ddl-auto if you don't want to create tables automatically or you can simply avoid the configuration. Please refer : How does spring.jpa.hibernate.ddl-auto property exactly work in Spring?
I have a Spring Boot 1.5 app which is configured with an application.yml file.
I need to manage the connection pool which is default - Tomcat.
The problem is that the application.yml has a datasources property for several datasources.
My global datasource.max-active=10 (UPDATE: datasource.tomcat.max-active=10 is ignored too) is being completely ignored (I created a test to see what datasource is being injected, and default maxActive in them is set to 100). I have to add it to every datasource separately to make the pool work the way I need it to.
The application.yml looks like this (this is only part of it), and it creates datasource with maxActive=10, but there is bunch of repetitions:
spring:
.... #bunch of stuff, deleted for simplicity
datasource: #Added by me, ignored by Spring
max-active: 10 #Added by me, ignored by Spring
datasources:
datasource1:
url: jdbc:mysql://url:port1
max-active: 10 #Added by me, works
datasource2:
url: jdbc:mysql://url:port2
max-active: 10 #Added by me, works
Question: what is the correct way to set the max-active property globally to avoid this repetition?
Thanks.
When you are using multiple data sources, spring boot does not provide a default data source auto-configuration. This also means you have to provide connection pool properties for each data source. I don't think it's possible to set it globally.
Instead, you can use the placeholder to set it once and use it everywhere.
custom:
max-active: 10
spring:
datasources:
datasource1:
url: jdbc:mysql://url:port1
max-active: ${custom.max-active}
datasource2:
url: jdbc:mysql://url:port2
max-active: ${custom.max-active}
You can find more info here: How to setup multiple connection pools when multiple datasources are used in Spring Boot?
This question already has answers here:
Spring Boot configure and use two data sources
(10 answers)
Closed 4 years ago.
I have a spring boot application that will be communicating with two databases (Cassandra and DB2). I'll be using spring data in this application.
Is it applicable to configure the data sources only in application.yml file, without writing java code. If so, how can I specify the dialect for each one?
Note: this application uses spring-data-cassandra for cassandra database and spring-data-jpa for db2 database.
For example:
spring:
datasource:
url: jdbc:db2://myRemoteHost:portNumber/MyDBName
username: username
password: password
driver-class-name: com.ibm.db2.jcc.DB2Driver
data:
cassandra:
cluster-name: cluster name
keyspace-name: keyspace name
port: myPortNumber
contact-points: host1.com
username: username
password: password
Note: This question is different from Spring Boot Configure and Use Two DataSources . My question is to know if it's applicable to configure the data sources only in application.yml file without doing it manually, while the other question explains how to do it manually.
I found that it's applicable for the case above, as the application uses spring-data-cassandra for cassandra database and spring-data-jpa for connecting to db2 database.
Spring boot is smart enough to figure out which repositories and entities are used by spring-data-jpa and which are used by spring-data-cassandra.
As long as you are using a different spring data type for each database, it' applicable.