how to use one database at a time from multiple ones in springboot - spring-boot

i am working on a spring boot project I am using multiple databases and all databases have same table I need to pass a number in the request based on the number I need to select one database from all databases and run the query any suggestion how to do it

Related

Multiple databases (Postgresql in RDS) but same spring repository and entity

I have a use case where I need to create exact same postgresql database in two different regions. Everything is same in these two databases i.e same schema and same tables and same data.
I have a use to achieve distributed transaction. So if a request land in region-a and write to region-a database to let's say Person table, then exact same record must be either written in Person table in both these database or if there is any error, write attempt should be rolled back.
I am trying to figure out if I can attach two different datasources with same Person Entity and CRUD repository in spring so the respoistory.save() method can write to Person table in both the databases.
So far, I have come across AbstractRoutingDataSource but that is for achieving multi tenancy in the databases. Other solutions are found are slightly different where use case is to write different records in different database (mostly sharding based on various data points).
Does spring provide any out of the box solution so I can achieve transactional write to same table in two different databases.
Does spring provide any out of the box solution so I can achieve transactional write to same table in two different databases.
Depends on your definition of "out of the box" - it doesn't itself implement distributed transactions, but does have support for using libraries that do. It is however relatively complicated to get everything working correctly, and requires additional components to be carefully configured in your runtime environment.
Spring Boot 2.x documentation on distributed transactions is here: https://docs.spring.io/spring-boot/docs/2.7.x/reference/htmlsingle/#io.jta
The Spring Boot 3.x documentation is here: https://docs.spring.io/spring-boot/docs/current/reference/html/io.html#io.jta but it's also worth noting that for 3.x, the Spring Boot team have changed direction and decided that integrated support should be provided by the relevant JTA provider (cf. https://github.com/spring-projects/spring-boot/issues/28589 ), and so there's projects like https://github.com/snowdrop/narayana-spring-boot

How to call database on multiple environments using Springboot JPA

I am new to Springboot and trying to build a small rest-service. We have a DB deployed on different environments (e.g. DEV, TEST). The rest-service will make a call to the appropriate database based on the received query param (e.g. ?env=TEST). The schemas of the deployed database are the same, the difference is only in connection string. I have some questions related to this task.
I read a few articles how to work with multiple databases using Spring JPA (for example this one: https://www.baeldung.com/spring-data-jpa-multiple-databases). It did work, but in the given example they get different entites from different databases using different queries, in my case the entity and the query is the same, but I still have to duplicate repositories, transactionManagers, entityManagers etc because of different datasources. And this is just two environments and I have more of them.
I have another thought that I might need to recreate the repository each time I process a request (to make the repository non-singleton). I am not sure if it is a good practice.
Maybe it worth to use JDBCTemplate instead of Spring JPA in this case?
Could you please suggest something how to approach such a task?

Latest by group query using Spring Boot JPA

I am using Spring Boot 2.5.0 for one of my test projects and need to get some data from one of the transaction tables. I need only latest record per group from this table. This problem has a solution given multiple times on SO, one of which is https://stackoverflow.com/a/1313293/841221.
However, I want to implement the same using Spring Boot Data JPA and not using a native query as using a native query would make me lose database independence.
Can someone please help me?

How can I create an in-memory test database when the table mappings are using other databases?

I'm trying to create some tests for an application that uses Spring and JPA (with Hibernate).
I want to use an in-memory database so that I can check if everything is working without having to depend on the main development server (which is an old Sybase installation), and also will allow me to isolate better the tests functionality.
Problem is, there are a lot of tables that are mapped using #Table("dbname..dbo.someviewname") to access views from other databases.
So, I was trying to use HSQLDB with DBunit, but HSQLDB understandbly does not allow to create tables with dots in their names.
How can I do tests against that?
Should I give up of the in-memory thing and do tests using the main Sybase development server (risking to ruin it for the other devs :P)?
From dbname.dbo.someviewname HSQLDB likely extracts dbname as catalog, dbo as schema and somewiewname as table name.
HSQLDB do allow creating tables which have dot in their names. That can be done by treating table name as delimited identifier:
#Table(name="\"dbname.dbo.someviewname\"")
But you do not want to use that, because then how names are treated is changed also for Sybase. If you can have separate orm.xml for tests, then you can add following to orm.xml:
<persistence-unit-defaults>
<delimited-identifiers/>
</persistence-unit-defaults>
It causes all database object names to be treated as delimited identifiers. Depending about your mappings and queries it can eventually work, but most likely you will face some problems. Likely best approach is not to have schema names in mappings and/or separate Sybase instance for tests.

HSQL Unit Test -- How to Create Multiple In-Memory Schemas?

I would like to use hsql within my DAO unit tests for a web application. The web app is written against mysql and uses three different schemas within the same mysql database. Some schemas has FK relationships with data in the other schemas. If I'm to unit test, I must be able to execute against a database that can hold multiple schemas.
I know that HSQL supports multiple schemas, but I don't know how to configure hsql to have multiple schemas set up for an in-memory database. I read that I can define multiple schemas in the server.properties file, but the file needs to be in the location of where the java class was called -- the junit.jar location? If so, that would be hard to support in my Java Maven application. How can I:
Run an in-memory hsql database to start up with three databases?
Where would I place the server.properties file in my Maven app?
Could I point hsql to use a server.properties file in a location other than where the junit jar is (that's a showstopper for me)?
Is it possible to configure multiple schemas for an in-memory database just via a tricked out jdbc url?
I wish I could untangle the schemas from each other, but that's not possible at this time.
Thanks for your help!
HSQLDB supports multiple schemas in the same database. Foreign keys can reference tables from different schemas. The following apply to the very latest HSQLDB 2.2.6 snapshot available from http://hsqldb.org
Before running your tests, execute CREATE SCHEMA schemaname for each schema.
Doesn't matter where, you can specify the absolute path on the command line arguments when running. See the HSQLD Guide and JavaDoc on server.
Yes.
No. You use the SQL statement to create the schemas.
Note you have two options for running HSQLDB, one is as a server, the other is as an embedded database. In the case of server, it must be started before the test run. In both cases, you need to connect to the database and create the schemas before your tests.
It is possible to create different db by setting db name. By default, it creates the db name as testdb, but in case we want to create multiple db, then set the name explicitly.
new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL).setName("DB_NAME")
.addScript("DDL.SQL")
.addScript("DML.SQL")
.build();
If you run the below line mutiple time, you can see the databases:
DatabaseManagerSwing.main(new String[] { "--url", "jdbc:hsqldb:mem:" + dbnaes, "--user", "sa", "--password", "" });

Resources