[hibernate-dev] multi-tenancy in Hibernate and JPA 2.1
Emmanuel Bernard
emmanuel at hibernate.org
Mon Apr 2 05:07:56 EDT 2012
I need to dive a bit into the JPA 2.1 PaaS proposal but here are a few comments in line int he mean time.
On 30 mars 2012, at 17:57, Steve Ebersole wrote:
> The scope of multi-tenancy in JPA 2.1 is pretty much set it seems, its
> just details at this point. And that scope is decidedly different from
> what I did for Hibernate. What we have in Hibernate is actually more
> encompassing.
>
> The terms being used to describe the differences are PaaS versus SaaS.
> What we have in Hibernate falls into what the spec committee is calling
> the SaaS category, essentially the ability to run one instance of the
> application (and therefore one instance of Hibernate) simultaneously
> handling multiple tenant requests. This is stated to be outside the
> scope of multi-tenancy for JPA 2.1. Instead JPA 2.1 will support what
> the committee is calling PaaS category, essentially multiple instances
> of the application (and therefore multiple instances of Hibernate) would
> be needed to handle multiple client requests.
>
> Essentially, you could largely achieve what is planned for multi-tenancy
> in JPA 2.1 using JPA 2.0 or earlier. But there will be some caveats to
> multi-tenancy in JPA that we will need to deal with, which I wanted to
> start discussing.
>
> First I think we should completely not use the existing multi-tenancy
> stuff in our support for JPA 2.1 multi-tenancy. Hibernate
> multi-tenancy, as it exists already, has some "overheads" thAt simply
> are not needed for the JPA use-case. For example, in Hibernate
> multi-tenancy (or "Saas multi-tenancy"), there is a need to know which
> of multiple available pools to use for getting Connections for use with
> particular tenants. But that is simply not needed for JPA multi-tenancy
> (or "PaaS multi-tenancy") because that running JPA provider instance can
> handle only one tenant at a time. Similar deal with second level cache
> keys: no need to encode tenant id into the key. That app will hold only
> one tenant's data (unless multiple apps share the same cache instances,
> but that's handle-able by prefixing the regions per app/tenant).
I am not sure how the PaaS multi-tenant config will look like exactly but if we can
automatically prefix the 2LC regions without adding an explicit mandatory property
that would be nice.
>
> If we do end up leveraging the existing multi-tenancy support, we will
> additionally need to know the type of multi-tenancy in effect. Here I
> mean this question of SaaS versus PaaS rather than the question of
> SEPARATE_DATABASE versus SEPARATE_SCHEMA versus DISCRIMINATED.
>
> JPA is proposing some limitations to available features based on the
> type of multi-tenancy (if any) is used in the application that we should
> go back and look at, even for our SaaS stuff. For example, in the
> SEPARATE_SCHEMA the current proposal is to disallow the deployment from
> referencing schemas/catalogs at all, which is a good idea. There is
> also proposed limitations on native-sql queries such that:
> 1) they would not be portably available if using DISCRIMINATED, although
> persistence providers could choose to support it if they can handle
> injecting any needed discriminator fragments
> 2) could not reference schemas/catalogs in the SEPARATE_SCHEMA, which is
> totally inline with the limitation on naming schemas/catalogs in general
> in SEPARATE_SCHEMA.
>
> Personally, I find all of the proposed limitations outlined above
> reasonable. There is a question of whether we would want to support
> native-sql queries in the DISCRIMINATED case. Take an example where the
> user supplies a query like [select ... from CUST_TBL c]. Obviously we
> need to limit that to return just their data, so we would need to
> instead pass a query along to the database like [select ... from
> CUST_TBL c where c.tenant = 'acme'] (assuming 'acme' is the current
> tenant identifier). It is a lot to bite off to support this
> unilaterally, because often folks are resorting to native-sql queries
> because they need to leverage some db-specific SQL syntax/feature and
> that is essentially impossible to properly parse and interpret. One
> option is that we could instead allow a placeholder: [select ... from
> CUST_TBL c where c.tenant = ${tenant}]. But even here we still have
> difficulty with being able to guarantee that we catch all cases. So in
> the end, I am not sure this is something we should be doing.
There is also a case to be made to not allow different tenants to see each other data.
so unless we can catch all malicious SQL queries, it's better disabled by default.
though I could see an app developer knowing his environment and enabling the
option if needed.
More information about the hibernate-dev
mailing list