[hibernate-dev] multi-tenancy and ConnectionProvider
Steve Ebersole
steve at hibernate.org
Wed Mar 23 17:58:09 EDT 2011
Well I think I am leaning towards a "parameter object" no matter what we do
otherwise. So call this param object interface ConnectionOptions. It would
have a single method today (err, tomorrow when I write all this :) to get the
tenant id.
The tenant id is really associated with the session. Either session
implements that interface or hands it off to a delegate it manages, but thats
the "scope"... the session.
So in your examnple, you would inject the entitymanager's session with the
proper tenant id. Ideally I want this to be specified up front when the
session is opended to make sure there is no possibility of changing it mid-
stream, but that further relies on
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2860
Anyway, in thinking about this sme more I think the way I really like is this:
1) ConnectionProvider remains as is
2) introduce a new provider contract (names as always are preliminary):
public interface SpecializedConnectionProvider extends ConnectionProvider {
public static interface ConnectionOptions {
public String getTenantIdentifier();
}
public Connection getSpecializedConnection(ConnectionOptions);
public void releaseSpecializedConnection(ConnectionOptions, Connection);
}
Having SpecializedConnectionProvider extend ConnectionProvider addressed
another issue I encountered when implementing this. How do you account for
situations where you need *some* connection? Like when reading
java.sql.DatabaseMetaData on "startup". The other option for that is to not
have SpecializedConnectionProvider extend ConnectionProvider (so they are back
to distinct hierarchies) and adding an extra method to
SpecializedConnectionProvider. This additional method would either give
access to a connection with out providing tenant information or if obtaining
java.sql.DatabaseMetaData is deemed the only acceptable use case there then
just have a method to scrape that info passing back DatabaseMetaData is not an
option if that is the decision because of
java.sql.DatabaseMetaData#getConnection
Also, I was not sure if there is really a need for a specialized "release this
connection" method in the case where SpecializedConnectionProvider extends
ConnectionProvider. There is still the ConnectionProvider#closeConnection
method. Now obviously if the herarchies are distinct we would need release
capability on both...
On Wednesday, March 23, 2011, at 04:24 pm, Chris Bredesen wrote:
> But 3 is how it's done today since we don't have the other solutions.
> So yeah it's magical, but people do manage to make it work. I will
> concede that it is not always perceived as straightforward, however.
>
> Something to think about in the grander scheme of things is how someone
> would deal with obtaining a tenant-specific connection when resource
> injection is in use. #3 solves this but what about #1 and #2? There
> are some pretty neat things that I can envision wrt CDI but I haven't
> thought through what the implementations would look like.
>
> @Inject @TenantSpecific @UserDatabase private EntityManager em;
>
> How would you drill the tenant information into the CP?
>
> -CB
>
> On 03/23/2011 04:25 PM, Adam Warski wrote:
> > I think for a user the best option (easiest to understand) would be 1).
> >
> > 3) is too magical. 2) is putting everything in one sack.
> >
> > Adam
> >
> > On Mar 22, 2011, at 10:21 PM, Steve Ebersole wrote:
> >> reference
> >> http://opensource.atlassian.com/projects/hibernate/browse/HHH-5697
> >>
> >> For multi-tenancy implemented by sepaerate schema we need the ability to
> >> tell the ConnectionProvider about the tenant for the given
> >> getConnection() request. I really see 3 approaches to this:
> >>
> >> 1) Have 2 hierarchies here. The current ConnectionProvider contract
> >> remains the same. Add a new MultiTenantConnectionProvider with methods
> >> accounting for tenant
> >> 2) Just alter the ConnectionProvider contract to pass information in.
> >> If we go this route I prefer the "parameter object" pattern where we
> >> pass in ConnectionOptions interface (see issue).
> >> 3) Use contextual lookup. ConnentionProviders interested in (or capable
> >> of understanding) mulit-tenancy would perform some kind of "contextual"
> >> (ThreadLocal, etc) lookup for the needed information.
> >>
> >> Thoughts? Discussions?
> >>
> >> ---
> >> Steve Ebersole<steve at hibernate.org>
> >> http://hibernate.org
> >> _______________________________________________
> >> hibernate-dev mailing list
> >> hibernate-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
---
Steve Ebersole <steve at hibernate.org>
http://hibernate.org
More information about the hibernate-dev
mailing list