In a recent role, I introduced Hibernate into an existing multi-tenant application. This required integrating Hibernate with an existing (custom) multi-tenant structure.
Hibernate – as standard – knows nothing about tenancies. So how can we accomplish such a task?
ConnectionProvider
Your basic approach here, is to implement a ConnectionProvider and configure it to be used by setting ‘hibernate.connection.provider_class’.
Hibernate will instantiate it, via a no-arg constructor, during startup.
ConnectionProvider implementations are configured within Hibernate code, and receive only properties. This means you can’t pass in objects, or access Spring beans, directly.
At runtime, Hibernate will call your ConnectionProvider at the exact moment it needs a connection. We can allocate & return a connection for the appropriate tenancy-specific data base.
But, how do we know which tenancy?
ThreadLocal
I first saw this technique, in the Spring framework. Spring’s ‘OpenSessionInViewFilter’ uses a ThreadLocal to make the current session available throughout application code.. without needing to pass it through deeply nested calls.
In our situation, we had created & configured a ServletFilter in the web.xml, which loaded the user’s current tenancy (from a session variable, set at login) into a thread-local.
This thread-local was made available application-wide, via a TenancyStatic class. Voila! Our MultitenantConnectionProvider can now find the current tenancy.
Conclusion
Multi-tenancy is one of the more complex requirements, arising in SaaS environments and real-world application development.
While tools like Hibernate and Spring help developers greatly, being able to engineer solutions to fit your specific requirements is advantageous.
One of the great achievements of modern frameworks is that, only a very small amount of custom code need be ‘plugged in’, & you can leverage the full functionality & reliability of these libraries.
This is just an overview, but should give you an insight as to just how easy multi-tenancy can be. Our full solution was little more complex.. we just had to set the thread-local for a few threaded tasks, and that’s all.
Shouldn’t all software development be so easy!
Do you have any thoughts on multi-tenancy with/ or without Hibernate? Let us know!
Hi Tom, i’m trying to implement a multi tenancy (schema based) spring-boot application using standard JPA (spring-boot) and Hibernate and Liquibase. But i have some problem with the configuration of Liquibase and the thread local, can you help me?
Can you post some code example?
Best Regard
Filippo