Spring-Boot multiple db target dependencies - java

Is there a 'community/Spring' approved method with Boot to have different datasource target for the same project?
Should I include both connector (H2 and Mysql) in the project dependencies and just change the jdbc url in my application.yml?
We are switching our tomcat instance to a Boot project, old habits of having jdbc jar as provided. I was wondering if this was still supported or desired in a boot fat jar/war exec.

If I understood Your question correctly, there are two scenarios, that You could be intrested in.
First is where You use both datasources at once in your project (ex. getting data from both H2 and MySQL in the same time, or one after another).
Second scenario is when You use two datasources but not at once, for example: H2 for test/debug project build, MySQL for production. Another sub-scenario is like You want something like primary/secondary datasources.
Solution for first scenario is to add two dependencies, disable Boot autoconfiguration (autoconfiguration won't work for multiple datasources) for databases and manually configure tho separate EntityManagers etc. (more info here: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html#howto-use-two-entity-managers)
Sorry that I can't provide any code sample but I can't access my work repo from home.
Moving to the second scenario what You can do is, use profiles.
You have to create separate profile and application-something.yml file for that profile. Inside you configure your second datasource, and then in dependencies you can make your second database dependency to add only with specific profile as well - but here im not 100% sure, I don't remember how we did it in work ;d.
And again, I cant paste any example but here is some help:
Profiles,
Profile-specific configuration files
An then there is a sub-scenario that I mentioned earlier. Marking datasource as #Primary But here I've never used it, I just know it exists: Link
Edit2: After some rethinking, I think this is the way to go with Boot and active profiles: Spring Boot Maven Plugin
Sorry for a lot of spam, and reconsiderations. That was quite confusing for sure.
Hope that helps,

Related

How to merge application.properties with application-default.properties and include in other test profiles with Spring Boot >2.4

We would like to merge src/main/resources/application.properties with additional default properties when running tests which in turn should be included by other (test) properties files activated via specific profiles in our Spring Boot application.
Up until Spring Boot 2.4 this worked quite well by having all common test properties in src/test/resources/application-default.properties to keep things DRY. Those were then automatically merged with the ones from src/main/resources/application.properties by Spring [1]. This allowed us to have our own set of default properties without requiring tests to specify an #ActiveProfiles("default").
Other (test) profiles could then have their own application-<profile>.properties with spring.profiles.include=default and then further extend the defaults.
With Spring Boot 2.4 I'm struggling with the new "rules":
I can no longer load application-default.properties from application-<profile>.properties since spring.profiles.include is no longer allowed in non profile-specific documents [2].
I don't want to introduce a src/test/resources/application.properties since I don't want to repeat everything from src/main/resources/application.properties. Also I don't want to load any activate any test-related profiles in the app's properties.
It looks like one solution could be to explicitly add spring.profiles.include=default to src/main/resources/application.properties to force the application to include the properties file with default properties which will work as before when it comes to running the actual application but consider src/test/resources/application-default.properties when running the tests.
Is this the way to go or are there smarter solutions to tackle this problem and still keep the properties free of redundancies?
spring.profiles.active=dev
add this config in application.properties file

Spring Boot properties that depend on profile-specific properties

I have a Spring Boot application which should connect to different servers in dev and prod, with many services running on those servers. To this point, I have created the configuration like this:
application.properties:
server.url.srv1=${server.url.base}/srv1
server.url.srv2=${server.url.base}/srv2
server.url.srv3=${server.url.base}/srv3
application-dev.properties:
server.url.base=http://192.168.86.17
application-prod.properties:
server.url.base=https://10.11.12.3
Yet when I initialize a bean argument with #Value("${server.url.srv1}"), I get a string of "${server.url.base}/srv1" and not "http://192.168.86.17/srv1" or "https://10.11.12.3/srv1" as expected.
Is this doable at all? It should be if the "${}" references are only resolved once all the config files are loaded, but this doesn't seem to be the case.
I have searched for an answer on both the Spring site, on Google (which pointed me to an otherwise useful Baeldung site), and here, but found nothing relevant to my particular question.
Placeholders in the application.properties should work. Please refer sample project I have added with your use case and it work as expected: https://github.com/itsprav/spring-profile-properties-using-placeholder
When you run your application you must have to set the specific spring-profile to be set in order to get the specific properties defined previously.
There is many ways to set these profiles.
Setting Profiles in different ways (JVM, Programmatically, Environment Variable...)

Can you set the compatibility mode on the Autoconfigured Spring Boot H2 test DB?

Is there a way to configure the H2 Compatibility Mode for the H2 Database that Spring Boot can auto configure to replace your regular database without just replacing it?
There are documented ways of disabling the autoconfiguration test database replacement:
https://stackoverflow.com/a/43557541/141042
I don't mind doing something like this, but most of the alternatives come with other complexities:
if you add a application.properties in your test classpath, this replaces your main application.properties during test runs, so then you're stuck maintaining two files (e.g. https://github.com/spring-projects/spring-boot/issues/10271)
if you set up a profile for test runs, then you have to make sure that any test needing the test database is marked with the profile
Is there a better way of doing this? I like the simplicity of the Spring Boot auto configured test database, but it seems like I have to force it into MySQL compatibility mode now to continue to work with my existing migrations.
So is there:
a way to configure the compatibility mode of h2 when spring autoconfigures the test database without disabling that mechanism?
a way of specifying the jdbc url for all tests without having to modify each test (e.g. to include a profile) or maintaining two application property files (e.g. a new application.properties in src/test/resources)
There isn't an option to set a custom URL for the embedded datasource that Spring Boot replaces in your tests. We offer a way to specify which connection type you want but that doesn't include the URL itself. I have no idea how easy we could add that but it's worth looking at least, I've created issue #19038
As for specifying the URL, you shouldn't add an application.properties in your test classpath for the reason you've mentioned. The SO thread you've referenced already has an answer that refers to application-test.properties.

Using Spring boot, is there any way to have multiple datasources using same models and repositories?

I'm trying to configure a Spring Boot application with two datasources using same repositories and models, but when spring boot start says that repositories are already defined and can't create another on the bean container. That's true I mean.. I accept the error..but I would like to know if there is any way to do this. Below an idea of what I would like to do
Datasoruce(H2) for local deploy ----> com.myapp.repositories
Datasource(SQLServer) for remote deploy ----> com.myapp.repositories
My problem is that even if I'm doing the deploy on my local machine ..I need my remote datasource to do some operation.. In other world both local and remote Datasource connections should be up during local deploy.
I found actually three solution:
The first is #Profile the #Configuration one for "prod" one for "dev"..but in my case don't work.
Second one is to put different repositories package for each configuration. This work but I need to move all repositories when I go live.
Third solution is to do always two configuration and don't specify the basePackages on the remote Datasource. This work but I need to change this parameter when I go live.
Is there any other solution to do this?
Thank you for help.

Multiple datasources with same repositories and entities

I have a current requirement of allowing multiple data sources for the same repositories/entities in spring boot using jpa.
What I've managed to find was always related to multiple datasources, with multiple repositories/entites.
However, here I would like to have the same repositories and entities (ie same database structure) for multiple datasources.
And based on same property, programmatically activate a specific datasource.
I've tried the setup demo'ed here: https://github.com/spring-projects/spring-data-examples/tree/master/jpa/multiple-datasources
And in both configurations use the same package in the factoryBean.setPackagesToScan() call. This does now work however, one datasource overrides the other.
My current test can be found here: https://github.com/nWidart/spring-data-multi-datasource/tree/master/src/main/java/com/example/multidatasources
It shows the 2 configuration files (client1 and client2) with a repository and entity. The controller has 2 endpoints for both data sources (not working).
Thanks!
you can do like below :
1. application.properties (as default) : as you see, you can switch between datasource files.
2. application-test.properties (sample)
I hope this can help you. :D

Categories