Hibernate5 multitenancy changing to hibernate.properties config file. (#1881)

* First commit for Hibernate 5 Multitenancy tutorial

* Changes to fix the code.

* Added hibernate begin transaction code.

* Changes to solve the multitenancy issue.

* Changes to integrate h2

* Changing configs to solve the error

* Changes to solve h2 error...

* Changes to fix H2 error.

* Cleaned POM.xml and changed entity name

* Changes table name to supplier

* Removed MySql Dep from pom.xml.

* Changes as per comment in the PR...

* Removed try-catch from test functions.

* Removing the hibernate xml config.

* Changed the formatting as per the formatter.

* Clean up after merge.

* # WARNING: head commit changed in the meantime

Merge remote-tracking branch 'upstream/master' into
hibernate5-multitenancy

Conflicts:
	hibernate5/pom.xml
	pom.xml
This commit is contained in:
Parth Joshi 2017-05-28 22:13:31 +05:30 committed by KevinGilmore
parent 8c8c01ebbb
commit efd2c2bd34
6 changed files with 141 additions and 80 deletions

View File

@ -15,6 +15,8 @@
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Maven plugins -->
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
@ -22,6 +24,11 @@
<artifactId>hibernate-core</artifactId> <artifactId>hibernate-core</artifactId>
<version>5.2.9.Final</version> <version>5.2.9.Final</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
@ -37,6 +44,32 @@
</resource> </resource>
</resources> </resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
<exclude>**/*LiveTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build> </build>
</project> </project>

View File

@ -1,5 +1,9 @@
package com.baeldung.hibernate; package com.baeldung.hibernate;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -20,44 +24,56 @@ import com.baeldung.hibernate.pojo.Supplier;
public class HibernateMultiTenantUtil { public class HibernateMultiTenantUtil {
private static SessionFactory sessionFactory; private static SessionFactory sessionFactory;
private static Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>(); private static Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>();
private static final String[] tenantDBNames = { "mydb1","mydb2"}; private static final String[] tenantDBNames = { "mydb1", "mydb2" };
public static SessionFactory getSessionFactory() throws UnsupportedTenancyException { public static SessionFactory getSessionFactory() throws UnsupportedTenancyException, IOException {
if (sessionFactory == null) { if (sessionFactory == null) {
Configuration configuration = new Configuration().configure(); // Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = configureServiceRegistry(configuration); ServiceRegistry serviceRegistry = configureServiceRegistry();
sessionFactory = makeSessionFactory (serviceRegistry); sessionFactory = makeSessionFactory(serviceRegistry);
// sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} }
return sessionFactory; return sessionFactory;
} }
private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) { private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) {
MetadataSources metadataSources = new MetadataSources( serviceRegistry ); MetadataSources metadataSources = new MetadataSources(serviceRegistry);
for(Class annotatedClasses : getAnnotatedClasses()) { for (Class annotatedClasses : getAnnotatedClasses()) {
metadataSources.addAnnotatedClass( annotatedClasses ); metadataSources.addAnnotatedClass(annotatedClasses);
} }
Metadata metadata = metadataSources.buildMetadata(); Metadata metadata = metadataSources.buildMetadata();
return metadata.getSessionFactoryBuilder().build(); return metadata.getSessionFactoryBuilder()
.build();
} }
private static Class<?>[] getAnnotatedClasses() { private static Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { return new Class<?>[] { Supplier.class };
Supplier.class
};
} }
private static ServiceRegistry configureServiceRegistry(Configuration configuration) throws UnsupportedTenancyException { private static ServiceRegistry configureServiceRegistry() throws UnsupportedTenancyException, IOException {
Properties properties = configuration.getProperties();
// Properties properties = configuration.getProperties();
Properties properties = getProperties();
connectionProviderMap = setUpConnectionProviders(properties, tenantDBNames); connectionProviderMap = setUpConnectionProviders(properties, tenantDBNames);
properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, new ConfigurableMultiTenantConnectionProvider(connectionProviderMap)); properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, new ConfigurableMultiTenantConnectionProvider(connectionProviderMap));
return new StandardServiceRegistryBuilder().applySettings(properties).build(); return new StandardServiceRegistryBuilder().applySettings(properties)
.build();
}
private static Properties getProperties() throws IOException {
Properties properties = new Properties();
URL propertiesURL = Thread.currentThread()
.getContextClassLoader()
.getResource("hibernate.properties");
FileInputStream inputStream = new FileInputStream(propertiesURL.getFile());
properties.load(inputStream);
System.out.println("LOADED PROPERTIES FROM hibernate.properties");
return properties;
} }
private static Map<String, ConnectionProvider> setUpConnectionProviders(Properties properties, String[] tenantNames) throws UnsupportedTenancyException { private static Map<String, ConnectionProvider> setUpConnectionProviders(Properties properties, String[] tenantNames) throws UnsupportedTenancyException {
@ -66,23 +82,27 @@ public class HibernateMultiTenantUtil {
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl(); DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
String tenantStrategy = properties.getProperty("hibernate.multiTenancy"); String tenantStrategy = properties.getProperty("hibernate.multiTenancy");
System.out.println("Strategy:"+tenantStrategy); System.out.println("Strategy:" + tenantStrategy);
properties.put(Environment.URL, tenantUrl(properties.getProperty(Environment.URL), tenant, tenantStrategy)); properties.put(Environment.URL, tenantUrl(properties.getProperty(Environment.URL), tenant, tenantStrategy));
System.out.println("URL:"+properties.getProperty(Environment.URL)); System.out.println("URL:" + properties.getProperty(Environment.URL));
connectionProvider.configure(properties); connectionProvider.configure(properties);
System.out.println("Tenant:"+tenant); System.out.println("Tenant:" + tenant);
providerMap.put(tenant, connectionProvider); providerMap.put(tenant, connectionProvider);
} }
System.out.println("Added connections for:"); System.out.println("Added connections for:");
providerMap.keySet().stream().forEach(System.out::println); providerMap.keySet()
.stream()
.forEach(System.out::println);
return providerMap; return providerMap;
} }
private static Object tenantUrl(String originalUrl, String tenant, String tenantStrategy) throws UnsupportedTenancyException { private static Object tenantUrl(String originalUrl, String tenant, String tenantStrategy) throws UnsupportedTenancyException {
if (tenantStrategy.toUpperCase().equals("DATABASE")) { if (tenantStrategy.toUpperCase()
.equals("DATABASE")) {
return originalUrl.replace(DEFAULT_DB_NAME, tenant); return originalUrl.replace(DEFAULT_DB_NAME, tenant);
} else if (tenantStrategy.toUpperCase().equals("SCHEMA")) { } else if (tenantStrategy.toUpperCase()
.equals("SCHEMA")) {
return originalUrl + String.format(SCHEMA_TOKEN, tenant); return originalUrl + String.format(SCHEMA_TOKEN, tenant);
} else { } else {
throw new UnsupportedTenancyException("Not yet supported"); throw new UnsupportedTenancyException("Not yet supported");

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.h2.Driver</property>
<property name="hibernate.connection.url">jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1</property>
<property name="hibernate.connection.username">sa</property>
<property name="connection.password"/>
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<property name="hibernate.multiTenancy">DATABASE</property>
</session-factory>
</hibernate-configuration>

View File

@ -0,0 +1,8 @@
hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
hibernate.connection.username=sa
jdbc.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.multiTenancy=DATABASE

View File

@ -1,55 +1,58 @@
package com.baeldung.hibernate; package com.baeldung.hibernate;
import com.baeldung.hibernate.pojo.Supplier;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Before;
import org.junit.Test;
import com.baeldung.hibernate.pojo.Supplier;
public class MultiTenantHibernateIntegrationTest { public class MultiTenantHibernateIntegrationTest {
@Test @Test
public void givenDBMode_whenFetchingSuppliers_thenComparingFromDbs () { public void givenDBMode_whenFetchingSuppliers_thenComparingFromDbs() throws UnsupportedTenancyException, IOException {
SessionFactory sessionFactory; SessionFactory sessionFactory = HibernateMultiTenantUtil.getSessionFactory();
try {
sessionFactory = HibernateMultiTenantUtil.getSessionFactory();
Session db1Session = sessionFactory Session db1Session = sessionFactory.withOptions().tenantIdentifier("mydb1").openSession();
.withOptions().tenantIdentifier("mydb1").openSession();
initDb1(db1Session); initDb1(db1Session);
Transaction transaction = db1Session.getTransaction(); Transaction transaction = db1Session.getTransaction();
transaction.begin(); transaction.begin();
Supplier supplierFromDB1 = (Supplier)db1Session.createCriteria(Supplier.class).list().get(0); Supplier supplierFromDB1 = (Supplier) db1Session.createCriteria(Supplier.class).list().get(0);
transaction.commit(); transaction.commit();
Session db2Session = sessionFactory Session db2Session = sessionFactory.withOptions().tenantIdentifier("mydb2").openSession();
.withOptions().tenantIdentifier("mydb2").openSession();
initDb2(db2Session); initDb2(db2Session);
db2Session.getTransaction().begin(); db2Session.getTransaction().begin();
Supplier supplierFromDB2 = (Supplier) db2Session.createCriteria(Supplier.class).list().get(0); Supplier supplierFromDB2 = (Supplier) db2Session.createCriteria(Supplier.class).list().get(0);
db2Session.getTransaction().commit(); db2Session.getTransaction().commit();
System.out.println(supplierFromDB1); System.out.println(supplierFromDB1);
System.out.println(supplierFromDB2); System.out.println(supplierFromDB2);
assertNotEquals(supplierFromDB1, supplierFromDB2);
assertNotEquals(supplierFromDB1, supplierFromDB2);
} catch (UnsupportedTenancyException e) {
e.printStackTrace();
}
} }
private void initDb1(Session db1Session) { private void initDb1(Session db1Session) {
System.out.println("Init DB1"); System.out.println("Init DB1");
Transaction transaction = db1Session.getTransaction(); Transaction transaction = db1Session.getTransaction();
transaction.begin(); transaction.begin();
db1Session.createSQLQuery("DROP ALL OBJECTS").executeUpdate(); db1Session.createSQLQuery("DROP ALL OBJECTS").executeUpdate();
db1Session.createSQLQuery("create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))").executeUpdate(); db1Session
.createSQLQuery(
"create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))")
.executeUpdate();
db1Session.createSQLQuery("insert into Supplier (id, country, name) values (null, 'John', 'USA')").executeUpdate(); db1Session.createSQLQuery("insert into Supplier (id, country, name) values (null, 'John', 'USA')").executeUpdate();
transaction.commit(); transaction.commit();
} }
@ -59,7 +62,10 @@ public class MultiTenantHibernateIntegrationTest {
Transaction transaction = db2Session.getTransaction(); Transaction transaction = db2Session.getTransaction();
transaction.begin(); transaction.begin();
db2Session.createSQLQuery("DROP ALL OBJECTS").executeUpdate(); db2Session.createSQLQuery("DROP ALL OBJECTS").executeUpdate();
db2Session.createSQLQuery("create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))").executeUpdate(); db2Session
.createSQLQuery(
"create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))")
.executeUpdate();
db2Session.createSQLQuery("insert into Supplier (id, country, name) values (null, 'Miller', 'UK')").executeUpdate(); db2Session.createSQLQuery("insert into Supplier (id, country, name) values (null, 'Miller', 'UK')").executeUpdate();
transaction.commit(); transaction.commit();
} }

View File

@ -0,0 +1,8 @@
hibernate.connection.driver_class=org.h2.Driver
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
hibernate.connection.username=sa
jdbc.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.multiTenancy=DATABASE