Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Using Hibernate to Implement Multi-tenant Cloud Architecture : Page 2

Hibernate is an excellent Java ORM tool but it lacks the features required to implement a multi-tenant cloud architecture. Don't let that stop you.




Application Security Testing: An Integral Part of DevOps

Multi-tenancy with Hibernate: Separate Schema Model

The model for a separate schema-based multi-tenant cloud architecture is simple to implement. PostgreSQL provides some excellent features for schema separation, which is useful in this scenario. In PostgreSQL, schema is like the namespace for the database. Access to schema with full qualified tenant_id (which in this case is schema name) can be used to separate one schema from the other. As an example, consider this simple SQL specific to PostgreSQL.

CREATE SCHEMA tenant1; CREATE SCHEMA tenant2; /*CREATE TABLE mytable; this will create table in public schema. We do not want do that */ CREATE TABLE tenant1.mytable(some_id varchar); CREATE TABLE tenant2.mytable(some_id varchar); /*INSERT INTO mytable VALUES('111'),('222'); we do not want to do this either */ INSERT INTO tenant1.mytable VALUES('111'),('222'); INSERT INTO tenant2mytable VALUES('111'),('222'); SELECT * FROM tenant1.mytable; SELECT * FROM tenant2.mytable;

Hibernate can handle this by telling the Session which tenant it belongs to, and consequently it can be handled by ConnectionProvider because it may provide a contract for obtaining JDBC connections. Steve Ebersole (Lead Developer, Hibernate) provided some examples on how to do this:

Session s = …; s.setTenant ("tenant 1");

Or you could pass tenant 1 along to the openSession call and then to the ConnectionProvider, or maybe pass the Session itself.

  1. public interface ConnectionProvider { public Connection getConnection(String tenant); }

  2. public interface ConnectionProvider { public Connection getConnection(Session session); }

  3. public interface ConnectionProvider { public static interface ConnectionOptions { public String getTenant(); } public Connection getConnection(ConnectionOptions options); }

Hibernate does not offer much direct API support in implementing the first model, but it is equipped to handle multi-tenancy. The features of PostgreSQL combined with Hibernate do make things easier, which may make this approach attractive.

Multi-tenancy with Hibernate: Discriminator-based Model

In this model, a particular field in a database table called tenant ID is used to uniquely identify a particular tenant. It is by this ID that you know which row belongs to which tenant. The application has to make sure that only relevant rows of the database are filtered out while manipulating data through query. Support for this method is planned for Hibernate 4+.

However, with the help of filters, you can implement discriminator-based multi-tenant cloud architecture today. Below is the complete code for accomplishing this. Product.java is the POJO class mapped to the database. The only non-specific addition is the field tenantId, which acts as the discriminator to make your class multi-tenant aware in database persistence.

package org.multitenant.dto; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import org.hibernate.annotations.Filter; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.Filters; import org.hibernate.annotations.ParamDef; @Entity @FilterDef(name="tenantFilter", parameters=@ParamDef(name="tenantId", type="string")) @Filters(@Filter(name="tenantFilter", condition="tenant_id=:tenantId")) public class Product { @Id private long id; @Column(name="tenant_id", nullable=false, updatable=false) private String tenantId; @Column(name="prod_name", nullable=false) private String prodName; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getTenantId() { return tenantId; } public void setTenantId(String tenantId) { this.tenantId = tenantId; } public String getProdName() { return prodName; } public void setProdName(String prodName) { this.prodName = prodName; } }

The Main.java file simulates a request interceptor. Observe that all sessions are enabled to tenant base Hibernate filter.

package org.multitenant.dto; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; public class Main { public static void main(String[] args) { Configuration configuration = new Configuration(); configuration.configure(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry); Session session=sessionFactory.openSession(); session.enableFilter("tenantFilter").setParameter("tenantId", "TID1"); session.beginTransaction(); Product p1=new Product(); p1.setId(222); p1.setTenantId("TID1"); p1.setProdName("Lollypop"); session.persist(p1); session.getTransaction().commit(); session.close(); session=sessionFactory.openSession(); session.enableFilter("tenantFilter").setParameter("tenantId", "TID1"); session.beginTransaction(); Product p2=(Product)session.createQuery("from Product").uniqueResult(); session.getTransaction().commit(); System.out.println("Tenant ID: "+p2.getTenantId()); System.out.println("ID : "+p2.getId()); System.out.println("Product Name : "+p2.getProdName()); session.close(); } }

Hibernate.cfg.xml contains the usual configuration; nothing particular to multi-tenancy here.

The Security Question

Providing data security is a big concern when implementing multi-tenant cloud architecture through Hibernate. To what level data are secure in a multi-tenant architecture implemented through discriminator is something to investigate. User concern about how secure their data are has been one of the burning issues in cloud computing. The level of security that should be provided by the database vendor versus the level that should be implemented with Hibernate or in the application level is a topic of debate. Hibernate does not yet have much direct API support in this arena either. However, Hibernate is an excellent (if not the most user-friendly) Java ORM tool. Developers like me are really eager for enhancements in multi-tenant cloud architecture features.

Manoj Debnath is a Java programmer with more than seven years of software development experience.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date