lundi 27 février 2017

Multi-Tenancy using JPA, Spring and Hibernate – Part One

Multi-tenancy allows an application to behave as multiple independent applications hosted for different clients (i.e. organisations). This might not sound impressive, however as the number of clients increase it becomes more evident that it is easier and more cost effective to run a single application hosted for all the clients rather than hosting an independent application for each client.
Multi-tenancy has become more popular lately and is very useful for the economy in software companies since it makes your service more affordable using cheaper installations/costs. This is because multi-tenancy can lead your business to a higher level of competitive differentiation.

How does multi-tenancy work?

Multi-tenancy allows a single application instance to be served for multiple tenants on a single hosting server. This is usually performed by either Separating databasesSeparating schemas or Sharing schemas.
This architecture therefore allows for a single instance to service different companies.
Multi-tenancy
Multi-tenancy works by using the concept of tenants, each tenant has access only to his corresponding data, even if they are in the same or different database. It means that you can have multiple tenants (usually one per client) who will use your application as if it were a single application. Amazing, isn’t it?

Multi-tenancy implementation – software architecture

Let’s start with the basic, multi-tenancy has 3 different ways to implement:
  • Separate-databases: Each tenant has its own database
  • Separate schemas: Tenants share common database but each tenant has its own set of tables (schema)
  • Shared schema: Tenants share common schema and are distinguished by a tenant discriminator column
No choice is better than another, every choice has different advantages and disadvantages, therefore it all boils down to what you want to compromise:
  • Quantity of tenants
  • Performance
  • Time of development
  • Reliability
  • Disaster recovery
  • And so on…
When you want to achieve a feature, it usually brings down another.
For instance: Separate-database is fully isolated, also it provides backup easily per tenant, however its performance isn’t so good as shared schema when there are a lot of clients.
For more comprehensive details about Multi-tenant architecture I suggest the following MSDN article which delves more into the topic. https://msdn.microsoft.com/en-us/library/aa479086.aspx

Multi-tenancy implementation

Hibernate, Spring, JPA

In this section we are going to use the Java specification for accessing POJOs to relational databases, that is the Java Persistent API (JPA).
As discussed earlier in the blog post, there are different approaches to implement Multi Tenancy, in this example we are going to use a separate database per tenant. In order to access the database we are going to use Hibernate which is a JPA Implementation.
We have chosen Hibernate because it is a well known ORM which has provided support for multi-tenancy implementation since version 4.  To use Hibernate with your Java application all you need to do is to implement two interfaces: MultitenantConnectionProvider and CurrentTenantIdentifierResolver.
Your custom implementation of these classes will mainly differ based on your chosen multi-tenancy implementation architecture as described in the previous sections. However, it should be noted that Hibernate does not yet support the shared schema architecture (see HHH-6054).

Hibernate sessions

Through the use of these sessions Hibernate is able to create transactions on entities. A session is opened and closed per transaction, when the session is created the tenantId is specified. Through the use of the tenantId, Hibernate can determine which resources to use, such that a tenant would access its (and only its) database.
In order to be able to create sessions, the SessionFactory class can be used. The SessionFactory needs to be provided with the tenantId so it is able to create a session appropriate to the database/schema that would be used by the tenant of the session being created. Below is an example of how a session is created:
Session session = sessionFactory .withOptions() .tenantIdentifier(yourTenantIdentifier) ... .openSession();

Aucun commentaire:

Enregistrer un commentaire