Multitenancy in Hibernate using both Schema and Database - java

The application has 2 separate databases, say:
DB1
DB2
and database of different companies are split across these 2 databases, like:
DB1
Company 1
Company 2
Company 3
Company 4
DB2
Company 5
Company 6
Company 7
Company 8
How can such a scenario be configured in hibernate?
All the examples refer either to Schema based multitenancy or Database multitenancy.
Is there any way to configure such a scenario?

To do that you should create two sessionFactory Bean in your config file. and in your DAO layer you call it using qualifier annotation.

You're going to have to create your own implementation of MultiTenantConnectionProvider that handles both database and schema level multitenancy. That should be the path of least resistance.
Here's some slightly outdated info about fighting with spring, hibernate and custom multitenancy: Setting up a MultiTenantConnectionProvider using Hibernate 4.2 and Spring 3.1.1

I will get strategy with separate database and in ConnectionProvider override method getConnection() to set schema.
I this case I can change databases and select specyfic schema for tenant.

Related

Is it possible to make Spring Boot JPA Hibernate application to automatically create tables with necessary columns and relations from JPA entities?

I am a newbie that only knows basics of Java Core. I have test task where I need to create simple REST Web Service with Spring Boot.
I wrote all the logic in Java Core, and now I try to wrap it in all these technologies.
I am using this guide:
https://spring.io/guides/tutorials/rest/
Here they have JPA entities and #Table annotation, where table name is specified, but there are no SQL scripts to create tables in this guide.
So I thought JPA will create database and tables for entities by itself, but when I uncomment #Table annotation it says "Cannot resolve table '<table_name>'"
I am using IntelliJ IDEA with Spring Boot Maven project with imported Spring Web, H2 and JPA (like the guide tells to do).
I also configured H2 Data Source and tested the connection: works fine. There is a schema, but no tables.
Here is my application.properties:
spring.h2.console.enabled=true
spring.h2.console.path=/h2_console
spring.datasource.url=jdbc:h2:~/kaylemains
spring.datasource.platform=h2
spring.datasource.initialization-mode=always
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.generate-ddl=true
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto = update
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
As in the guide, I add entities in LoadDatabase class like this:
#Bean
CommandLineRunner initTournaments(TournamentRepository repository) {
return args -> {
log.info("Preloading " + repository.save(new Tournament("Kayle Mains Competition: Summoner's Gorge", 16)));
};
}
So my question is: can I have file-stored H2 database and do everything with the it (including table creation) from my Java code?
OR it is necessary to create tables manually (by writing SQL scripts with CREATE TABLE) and construct them so that all entities work fine? (that means defining foreign key columns etc.), and only after that will JPA be able to work with this database? Do I need to add #Column annotation to every field, and JPA won't do it by itself for its Entities?
Why am I getting this error of "Cannot resolve table"? Of course it cannot be resolved because it does not exist yet, I thought JPA & Hibernate will create it for me based on entity classes...
Here in Baeldung you have all the information about the properties to ddl generation
Spring provides a JPA-specific property which Hibernate uses for DDL generation: spring.jpa.hibernate.ddl-auto.
create – Hibernate first drops existing tables, then creates new tables
update – the object model created based on the mappings (annotations or XML) >is compared with the existing schema, and then Hibernate updates the schema >according to the diff. It never deletes the existing tables or columns even if >they are no more required by the application
create-drop – similar to create, with the addition that Hibernate will drop >the database after all operations are completed. Typically used for unit testing
validate – Hibernate only validates whether the tables and columns exist, otherwise it throws an exception
none – this value effectively turns off the DDL generation
We have to set the value carefully or use one of the other mechanisms
to initialize the database.
If the problem is still present go to Settings -> Inspections, and uncheck the option "Unresolved database references in annotation"

Dynamically create schema in Spring boot application

I have a Spring boot application that uses JPA with Hibernate. It already connect to a primary data source for all transactions.
Now the task in hand is that I need to dynamically create Database Schema in a different database. For instance,
For project 1, create schema 1 in Database X
For project 2, create schema 2 in Database X
Later, these databases will be used by others externally. I am looking for the best way to get this done.
In case of defining multiple datasources in spring boot project, you have to declare associated beans in your configuration. With spring.jpa.hibernate.ddl-auto=create it will automatically create the schema in right database as answered here

Spring multi tenancy

I have two databases: Oracle and PostgreSQL where I have multiple schemas - one per each customer. I need to have an opportunity to route datasources by web request. I tried to use Spring's AbstractRoutingDatasource but it works only with single dialect. Are there any other solutions for this task?
I found a solution. You can explicity tell Hibernate which dialect to choose using hibernate.dialect property. So you can implement your own dialect extends org.hibernate.dialect.Dialect class, override all public methods and delegate calls to specific dialects. The good thing is Hibernate calls this (Dialect's) methods before performing any database requests. In my specific case I've implemented a custom dialect with map of dialects I need for my project and now I can use the same repositories and freely choose Postgresql, Oracle or MySQL depending on logged in user

Fallback Database with Hibernate

do someone of you know a way to have 2 Databases running parallel?
We are using Hibernate 4 and as a main database Postgres 9.3 - this db is hosted on another machine then the application - if the database is down we still have to save some stuff.
So first intention was to write it into a csv, but I'm not a friend of writing stuff into an unordered file. So I want just to use a fallback Database (thinking of H2 Database). Does someone has experience with such a construct?
We are also using Spring 4 - I would just set up another datasource + sessionfactory + transactionmanager - and add the name at the #Transactional method to use the right manager. any other ideas?
Thank you!!
You can extend the Spring AbstractRoutingDataSource and configure two actual data sources:
a primary PostgreSQL data source
a secondary H2 data source
The application logic will see only one data source, which is the router which will decide which data source is going to switch to on demand.
When the primary data source is down you need to instruct the router to pick the fall-back H2 one.

How do I connect to multiple databases with one persistence unit?

I am using JPA with Hibernate as my JPA provider. My application need to connect to database defined in persistence.xml (default persistence unit) grab multiple configured systems from table and create for each of them EntityManagerFactory (systems differ only in connection params, dialect and driver).
Is it possible to do it with "template" persistence unit? For now I'm using different copy persistence unit for each system but it's seems senseless.
You probably need to write your own JCA compliant connector that wraps the distinct DB connectors and expose that via JPA:

Categories

Resources