I have a multitenant system currently working with python. I have different schemas for different tenants. Now we are planning to change the system to spring boot.
How can we change/select the schema based on the request in JPA/Hibernate?
You can set the following property dynamically -
spring.jpa.properties.hibernate.default_schema=MYSCHEMA. For more advanced concept of using multiple datasources take a look at AbstractRoutingDatasource
Related
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
I created user in oracle database and I am trying to create session but I find many ways in spring boot so what is the easy way if I want to create classe connections using the Username and Password ?
You can jdbc template, spring data JDBC or spring data JPA, well depending on your use case.
If your data model is quite complex, you should avoid using the JDBC template as you will need to write prepared statements which can be cumbersome. JPA will allow you to use object-oriented programming principles and also will help you map the entities to your database columns.
For example, if you are going to use spring data JPA, you need to set the application properties as follows:
spring.datasource.type=oracle.oracleucp.jdbc.UCPDataSource
spring.datasource.oracleucp.connection-factory-class-name=oracle.jdbc.pool.OracleDataSource
spring.datasource.oracleucp.sql-for-validate-connection=select * from dual
spring.datasource.oracleucp.connection-pool-name=UcpPoolBooks
spring.datasource.oracleucp.initial-pool-size=5
spring.datasource.oracleucp.min-pool-size=5
spring.datasource.oracleucp.max-pool-size=10
This would behind the scene create an Oracle Datasource. In this example, we are using Oracle Universal Connection Pooling. You can also use HikariCP which is quite popular.
check this out
If you want to use UCP with above properties then you must have SpringBoot version higher than 2.4.0.
Check out the Spring Boot code sample on GitHub.
I am implementing a Spring Boot application which will be providing a multitenant environment. That is achieved in my case by using a database schema for each customer. Example see this project.
Now I am wondering how to implement tenant-specific configurations. I am using #ConfigurationProperties to bundle my property values, but these are getting instantiated once and not for each tenant.
What if I would like to use Spring Cloud Config with multiple tenant specific git repository as an configuration backend. Would it be possible when using a jdbc backend for Spring Cloud Config?
Is there any way with default Spring mechanisms or do I have to implement a database based configuration framework myself?
Edit: For example I have two tenants called Tenant1 and Tenant2. Both are running over the same application in the same context and are writing in the database schemes tenant_1 and tenant_2.
Identification of tenants is happening over keycloak (see Spring Keycloak multi tenant example). So I identify the tenantId from the jwt token and select the database connection like described here.
But now I would need the same mechanism for #Configuration beans. Since #Configuration beans are as far as I know Singletons, so there is always ONE configuration per application scope, and not ONE configuration per tenant.
So using Spring Cloud Config Tenant1 is using https://git-url/tenant1, Tenant2 is using Hashicorp Vault as backend and perhaps Tenant3 will be using a jdbc based configuration backend. And all of that in ONE (of course scalable) application.
In case your application uses tenant specific files (html templates etc), the following can be applied. As I have used the below approach for handling many tenants and works fine and easy to maintain.
I would suggest that you maintain a consistent configuration source (JDBC) for all of your tenant configurations. This helps you have a single source that is cacheable and scalable for your application. Also, you could have your tenants navigate to a configuration page to manage their settings and alter them to suit their needs at any point of time on the fly. (Example Settings: Records Per Page, Theme, Logo, Filters etc...)
Having the tenant configuration in files in git will be a difficult task when you wanted to auto-provision tenant's when they sign-up as it will involve couple of distributed services. Having them in a TenantSettings table with the tenantId as a column could help you get the data in no time and will be easy.
You can use Spring Cloud Config for your scenario and it is adoptable. It is easily configurable and provides out of the box features. For your specific scenario, you can have any number of microservices running yet all controlled by one Spring Cloud Config Server which is connected to one Git Repository. Your all microservices are asking configuration properties from Spring Cloud Config Server and it is directly fetching properties from Git Repository. That repository can have multiple property files. It can hold common properties for all the microservices or specific service based configuration properties. If you want to keep confidential properties more securely, that is also made possible via HashiCorp vault. I will leave an image below for you to get a better idea about this concept.
In the below image, you can see the Git Repository with common configuration property files and specific configuration property files for different services yet in same repository.
I will add another image for you to get a better idea how does this can be arranged with application profiles as well.
Finally I will add something additional to show the power of Spring Cloud Config and out of the box features it allows us to play with. You can automatically refresh configuration properties in running application as well. You can configure Spring Cloud Config to do that. I will add an architectural diagram to achieve that.
References for this answer is taken from Spring in Action, Fifth Edition
Craig Walls
I am using spring data r2dbc in my new project and need to connect multiple data sources like A data source and B data source.
Is there a way to connect multiple data sources using r2dbc?
Could I get an example or a document if there is a way?
My stacks are below:
Spring Boot 2.3.0.M4
Spring WebFlux
Spring Data R2DBC
If you want to use multiple datasources in a single application, check my multi r2dbc connection factories example.
If you need a multi-tenant like feature check this multi-tenancy-r2dbc example.
I solved this issue using AbstractRoutingConnectionFactory you can check Add support for AbstractRoutingConnectionFactory
How can I generate an entity(and a database table) in a different schema other than the default public schema for an existing Jhipster(4.6.2) project generated with spring boot and AngularJS as the technology stack. [Database - Postgresql]
I am very interested if it is possible. Otherwise one simple way to reach that: you could try to generate the entity using the jhipster command jhipster entity <entityName> --[options] see for more details.
And customize your application to use multiple databases by following this excellent article: https://www.baeldung.com/spring-data-jpa-multiple-databases