Validate multi-tenancy configuration (if configured) during JPA bootstrap

Description

I tried to use db schema based multi tenancy with hibernate jpa / entitymanager. I use the following properties in persistence.xml:

<property name="hibernate.multiTenancy" value="SCHEMA"/>
<property name="hibernate.tenant_identifier_resolver" value="com.xoricon.persistence.bo.multitenancy.test.SchemaBasedTenantResolver"/>
<property name="hibernate.multi_tenant_connection_provider" value="com.xoricon.persistence.bo.multitenancy.test.SchemaBasedMultiTenantConnectionProvider"/>

Both instances (SchemaBasedTenantResolver / SchemaBasedMultiTenantConnectionProvider) will be instantiated by hibernate.
When i call:

EntityManagerFactory lEntityManagerFactory= Persistence.createEntityManagerFactory("orm1");
EntityManager lManager = lEntityManagerFactory.createEntityManager();

I get:

System.out: SchemaBasedMultiTenantConnectionProvider.getAnyConnection()
System.out: SchemaBasedTenantResolver.<init>()
E
Time: 1,53
There was 1 error:
1) test1(com.xoricon.persistence.bo.multitenancy.test.SchemaBasedMultiTenancyTest)org.hibernate.HibernateException: SessionFactory configured for multi-tenancy, but no tenant identifier specified
at org.hibernate.internal.AbstractSessionImpl.<init>(AbstractSessionImpl.java:82)
at org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:231)
at org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1831)
at org.hibernate.ejb.EntityManagerImpl.getRawSession(EntityManagerImpl.java:121)
at org.hibernate.ejb.EntityManagerImpl.getSession(EntityManagerImpl.java:98)
at org.hibernate.ejb.AbstractEntityManagerImpl.setDefaultProperties(AbstractEntityManagerImpl.java:268)
at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:180)
at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:90)
at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:178)
at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:173)
at com.xoricon.persistence.bo.multitenancy.test.SchemaBasedMultiTenancyTest.test1(SchemaBasedMultiTenancyTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xoricon.persistence.bo.multitenancy.test.SchemaBasedMultiTenancyTest.main(SchemaBasedMultiTenancyTest.java:51)

FAILURES!!!
Tests run: 1, Failures: 0, Errors: 1

In System.out "SchemaBasedTenantResolver.<init>()" shows, that my CurrentTenantIdentifierResolver has been instantiated. But Hiberante did not call method "public String resolveCurrentTenantIdentifier()".
I expect, that Hibernate uses the CurrentTenantIdentifierResolver to get the current tenant id.

In JPA i cannot set the tenant on the Session, because the exception above occures before Session has been created. I can access the Session only by EntityManager.getDelegate(). But as shown above, i cannot create an EntityManager instance.

Environment

Hibernate 4.1.2, using JPA

Activity

Show:
Steve Ebersole
May 15, 2012, 2:00 PM

Not going to sit here and argue this. Its clearly not a bug.

Stefan Schulze
May 15, 2012, 3:04 PM

Ok, doesn't matter if we call it bug or feature.
You said it'd be possible to repurposing CurrentTenantIdentifierResolver. Could you outline, what would be necessary to do this? If it's simply done by changing the javadoc or something I can resolve, I would create a feature request about repurposing the Resolver, add both pull-requests (329 and 338) to this feature-request and link and as fixed by the feature request.
Is this a viable solution?

Steve Ebersole
May 15, 2012, 6:35 PM

To me, "re-purposing" of CurrentTenantIdentifierResolver comes under HHH-7306. Then HEM support for core multi-tenancy simply picks up on top of that

However, there are still things to think through like how to bridge passed in datasource info (PersistenceUnitInfo) with multi-tenancy support. Most likely all we can really do is validation. If a datasource is given, we really need to expect org.hibernate.MultiTenancyStrategy#SCHEMA (provided a MultiTenantConnectionProvider is also specified) or org.hibernate.MultiTenancyStrategy#DISCRIMINATOR (currently not implemented). org.hibernate.MultiTenancyStrategy#NONE is obviously OK as well. But org.hibernate.MultiTenancyStrategy#DATABASE is simply not going to be workable.

And just in general, support for multi-tenancy from HEM is completely not scoped out. So we need to think through all the little details.

Stefan Schulze
May 26, 2012, 11:48 PM

Hi Steve,

thank you for the great fix for HHH-7306. According to the JUnit-test I added in pull-request #338 this not only fixes but HHH-7312, too.
I'm not really familiar with JPA and its Hibernate-implementation - so I'm not sure if the proposed testcase creates a valid JPA-scenario (I think there is no PersistenceUnitInfo involved) and is really fixed by your commit. Could you please verify this and, if really fixed, mark this issue accordingly?

Steve Ebersole
January 28, 2014, 10:07 PM

As I said in earlier comments, the fix done in was part of the solution. There are other things that could/should be done in HEM usage, which again I outlined above. Mostly it comes down to validation tbh. Mainly it comes down to making sure that when the persistence.xml settings are incorrect for multi-tenancy support we are able to give constructive feedback as to what went wrong. We don't have that today.

Since multi-tenancy works in HEM assuming you have everything configured correctly, lets just change the subject here to "Validate multi-tenancy configuration (if configured) during JPA boot strap".

Assignee

Unassigned

Reporter

Oriel Maute

Fix versions

None

Labels

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Minor
Configure