diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index fdca4dea70..bdc6c6400c 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -1824,6 +1824,10 @@ public final class SessionFactoryImpl this.connectionReleaseMode = settings.getConnectionReleaseMode(); this.autoClose = settings.isAutoCloseSessionEnabled(); this.flushBeforeCompletion = settings.isFlushBeforeCompletionEnabled(); + + if ( sessionFactory.getCurrentTenantIdentifierResolver() != null ) { + tenantIdentifier = sessionFactory.getCurrentTenantIdentifierResolver().resolveCurrentTenantIdentifier(); + } } protected TransactionCoordinatorImpl getTransactionCoordinator() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/CurrentTenantResolverMultiTenancyTest.java b/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/CurrentTenantResolverMultiTenancyTest.java new file mode 100644 index 0000000000..f13771b6d1 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/CurrentTenantResolverMultiTenancyTest.java @@ -0,0 +1,77 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.multitenancy.schema; + +import org.junit.Assert; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; +import org.hibernate.context.spi.CurrentTenantIdentifierResolver; + +import org.hibernate.testing.TestForIssue; + +/** + * SessionFactory has to use the {@link CurrentTenantIdentifierResolver} when + * {@link SessionFactory#openSession()} is called. + * + * @author Stefan Schulze + * @author Steve Ebersole + */ +@TestForIssue(jiraKey = "HHH-7306") +public class CurrentTenantResolverMultiTenancyTest extends SchemaBasedMultiTenancyTest { + + private TestCurrentTenantIdentifierResolver currentTenantResolver = new TestCurrentTenantIdentifierResolver(); + + + @Override + protected Configuration buildConfiguration() { + Configuration cfg = super.buildConfiguration(); + cfg.setCurrentTenantIdentifierResolver( currentTenantResolver ); + return cfg; + } + + @Override + protected Session getNewSession(String tenant) { + currentTenantResolver.currentTenantIdentifier = tenant; + Session session = sessionFactory.openSession(); + Assert.assertEquals( tenant, session.getTenantIdentifier() ); + return session; + } + + + private static class TestCurrentTenantIdentifierResolver implements CurrentTenantIdentifierResolver { + private String currentTenantIdentifier; + + @Override + public boolean validateExistingCurrentSessions() { + return false; + } + + @Override + public String resolveCurrentTenantIdentifier() { + return currentTenantIdentifier; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java b/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java index 1e7af86455..d20f253416 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java @@ -59,32 +59,24 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { private ServiceRegistryImplementor serviceRegistry; - private SessionFactoryImplementor sessionFactory; + protected SessionFactoryImplementor sessionFactory; @Before public void setUp() { - acmeProvider = ConnectionProviderBuilder.buildConnectionProvider( "acme" ); - jbossProvider = ConnectionProviderBuilder.buildConnectionProvider( "jboss" ); - AbstractMultiTenantConnectionProvider multiTenantConnectionProvider = new AbstractMultiTenantConnectionProvider() { - @Override - protected ConnectionProvider getAnyConnectionProvider() { - return acmeProvider; - } + AbstractMultiTenantConnectionProvider multiTenantConnectionProvider = buildMultiTenantConnectionProvider(); + Configuration cfg = buildConfiguration(); - @Override - protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) { - if ( "acme".equals( tenantIdentifier ) ) { - return acmeProvider; - } - else if ( "jboss".equals( tenantIdentifier ) ) { - return jbossProvider; - } - throw new HibernateException( "Unknown tenant identifier" ); - } - }; + serviceRegistry = (ServiceRegistryImplementor) new ServiceRegistryBuilder() + .applySettings( cfg.getProperties() ) + .addService( MultiTenantConnectionProvider.class, multiTenantConnectionProvider ) + .buildServiceRegistry(); + sessionFactory = (SessionFactoryImplementor) cfg.buildSessionFactory( serviceRegistry ); + } + + protected Configuration buildConfiguration() { Configuration cfg = new Configuration(); - cfg.getProperties().put( Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE ); + cfg.getProperties().put( Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA ); cfg.setProperty( Environment.CACHE_REGION_FACTORY, CachingRegionFactory.class.getName() ); cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); cfg.addAnnotatedClass( Customer.class ); @@ -143,18 +135,34 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { cfg.generateDropSchemaScript( ConnectionProviderBuilder.getCorrespondingDialect() ), cfg.generateSchemaCreationScript( ConnectionProviderBuilder.getCorrespondingDialect() ) ).execute( // so stupid... - false, // do not script the export (write it to file) - true, // do run it against the database - false, // do not *just* perform the drop - false // do not *just* perform the create + false, // do not script the export (write it to file) + true, // do run it against the database + false, // do not *just* perform the drop + false // do not *just* perform the create ); + return cfg; + } - serviceRegistry = (ServiceRegistryImplementor) new ServiceRegistryBuilder() - .applySettings( cfg.getProperties() ) - .addService( MultiTenantConnectionProvider.class, multiTenantConnectionProvider ) - .buildServiceRegistry(); + private AbstractMultiTenantConnectionProvider buildMultiTenantConnectionProvider() { + acmeProvider = ConnectionProviderBuilder.buildConnectionProvider( "acme" ); + jbossProvider = ConnectionProviderBuilder.buildConnectionProvider( "jboss" ); + return new AbstractMultiTenantConnectionProvider() { + @Override + protected ConnectionProvider getAnyConnectionProvider() { + return acmeProvider; + } - sessionFactory = (SessionFactoryImplementor) cfg.buildSessionFactory( serviceRegistry ); + @Override + protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) { + if ( "acme".equals( tenantIdentifier ) ) { + return acmeProvider; + } + else if ( "jboss".equals( tenantIdentifier ) ) { + return jbossProvider; + } + throw new HibernateException( "Unknown tenant identifier" ); + } + }; } @After @@ -175,14 +183,14 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { @Test public void testBasicExpectedBehavior() { - Session session = sessionFactory.withOptions().tenantIdentifier( "jboss" ).openSession(); + Session session = getNewSession("jboss"); session.beginTransaction(); Customer steve = new Customer( 1L, "steve" ); session.save( steve ); session.getTransaction().commit(); session.close(); - session = sessionFactory.withOptions().tenantIdentifier( "acme" ).openSession(); + session = getNewSession("acme"); try { session.beginTransaction(); Customer check = (Customer) session.get( Customer.class, steve.getId() ); @@ -193,7 +201,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { session.close(); } - session = sessionFactory.withOptions().tenantIdentifier( "jboss" ).openSession(); + session = getNewSession("jboss"); session.beginTransaction(); session.delete( steve ); session.getTransaction().commit(); @@ -203,7 +211,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { @Test public void testSameIdentifiers() { // create a customer 'steve' in jboss - Session session = sessionFactory.withOptions().tenantIdentifier( "jboss" ).openSession(); + Session session = getNewSession("jboss"); session.beginTransaction(); Customer steve = new Customer( 1L, "steve" ); session.save( steve ); @@ -211,7 +219,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { session.close(); // now, create a customer 'john' in acme - session = sessionFactory.withOptions().tenantIdentifier( "acme" ).openSession(); + session = getNewSession("acme"); session.beginTransaction(); Customer john = new Customer( 1L, "john" ); session.save( john ); @@ -223,7 +231,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { // make sure we get the correct people back, from cache // first, jboss { - session = sessionFactory.withOptions().tenantIdentifier( "jboss" ).openSession(); + session = getNewSession("jboss"); session.beginTransaction(); Customer customer = (Customer) session.load( Customer.class, 1L ); Assert.assertEquals( "steve", customer.getName() ); @@ -235,7 +243,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { sessionFactory.getStatisticsImplementor().clear(); // then, acme { - session = sessionFactory.withOptions().tenantIdentifier( "acme" ).openSession(); + session = getNewSession("acme"); session.beginTransaction(); Customer customer = (Customer) session.load( Customer.class, 1L ); Assert.assertEquals( "john", customer.getName() ); @@ -250,7 +258,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { sessionFactory.getCache().evictEntityRegions(); // first jboss { - session = sessionFactory.withOptions().tenantIdentifier( "jboss" ).openSession(); + session = getNewSession("jboss"); session.beginTransaction(); Customer customer = (Customer) session.load( Customer.class, 1L ); Assert.assertEquals( "steve", customer.getName() ); @@ -262,7 +270,7 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { sessionFactory.getStatisticsImplementor().clear(); // then, acme { - session = sessionFactory.withOptions().tenantIdentifier( "acme" ).openSession(); + session = getNewSession("acme"); session.beginTransaction(); Customer customer = (Customer) session.load( Customer.class, 1L ); Assert.assertEquals( "john", customer.getName() ); @@ -272,17 +280,21 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { session.close(); } - session = sessionFactory.withOptions().tenantIdentifier( "jboss" ).openSession(); + session = getNewSession("jboss"); session.beginTransaction(); session.delete( steve ); session.getTransaction().commit(); session.close(); - session = sessionFactory.withOptions().tenantIdentifier( "acme" ).openSession(); + session = getNewSession("acme"); session.beginTransaction(); session.delete( john ); session.getTransaction().commit(); session.close(); } + protected Session getNewSession(String tenant) { + return sessionFactory.withOptions().tenantIdentifier( tenant ).openSession(); + } + }