Technology: hibernate-core4.2.5, Spring3.1
Project Type: Web Application
Problem Statement: We are implementing hibernate multi tenancy using SCHEMA approach.We are facing problem while getting sessionfactory by making a rest call to RegisterController.java(/login)
hibernate.cfg.xml
Code:
```
`<hibernate-configuration>
   <session-factory>
      <!-- Database connection settings -->
      <property name="hibernate.connection.url">jdbc:mysql://localhost/</property>
      <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="hibernate.connection.username">root</property>
      <property name="hibernate.connection.password"></property>
      <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
      
      <!-- SQL dialect -->
      <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
      <!-- Echo all executed SQL to stdout -->
      <property name="show_sql">true</property>
      <!-- Enable Hibernate's automatic session context management -->
      <property name="current_session_context_class">thread</property>
      <!-- Drop and re-create the database schema on startup 
      <property name="hbm2ddl.auto">none</property>-->
      
      <property name="hibernate.multiTenancy">SCHEMA</property>
      <property name="hibernate.tenant_identifier_resolver">com.techmust.SchemaResolver</property>
      <property name="hibernate.multi_tenant_connection_provider">com.techmust.MultiTenantProvider</property>
      
      <!-- <mapping resource="com/techmust/resource/login.hbm.xml"/> -->
   </session-factory>
</hibernate-configuration>        `
```
HibernateUtil.java
Code:
```
Configuration oConfiguration = new Configuration ();
         oConfiguration.configure("hibernate.cfg.xml");
         m_oLogger.debug("HibernateUtil Configuration:" + oConfiguration);
         
         ServiceRegistryBuilder oServiceRegistryBuilder =  new ServiceRegistryBuilder();
         ServiceRegistryBuilder oBuilder = oServiceRegistryBuilder.applySettings( oConfiguration.getProperties() );
         ServiceRegistry oServiceRegistry = oBuilder.buildServiceRegistry();
         
         m_oLogger.debug("HibernateUtil :oServiceRegistry " + oServiceRegistry);
         
         sessionFactory = oConfiguration.buildSessionFactory(oServiceRegistry);
         
         m_oLogger.debug("HibernateUtil :" + sessionFactory);
```
MultiTenantProvider.java
Code:
```
public class MultiTenantProvider implements MultiTenantConnectionProvider , ServiceRegistryAwareService  {
    
   private static final long serialVersionUID = 4368575201221677384L;
   
   private DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl ();
   
   @Override
   public boolean supportsAggressiveRelease() {
      return false;
   }
 
   @Override
   public void injectServices(ServiceRegistryImplementor serviceRegistry)
   {
      Map lSettings = serviceRegistry.getService(ConfigurationService.class).getSettings();
      
      connectionProvider.injectServices(serviceRegistry);
      connectionProvider.configure(lSettings);
   }
 
   @Override
   public boolean isUnwrappableAs(Class clazz) {
      return false;
   }
 
   @Override
   public <T> T unwrap(Class<T> clazz) {
      return null;
   }
 
   @Override
   public Connection getAnyConnection() throws SQLException {
      final Connection connection = connectionProvider.getConnection();
      return connection;
   }
 
   @Override
   public Connection getConnection(String tenantIdentifier) throws SQLException {
      final Connection connection = getAnyConnection();
      try {
         connection.createStatement().execute( "USE " + tenantIdentifier );
      }
      catch (SQLException e) {
         throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]", e);
      }
      return connection;
   }
 
   @Override
   public void releaseAnyConnection(Connection connection) throws SQLException {
      try {
         connection.createStatement().execute( "USE 'public'" );
      }
      catch (SQLException e) {
         throw new HibernateException("Could not alter JDBC connection to specified schema [public]", e);
      }
      connectionProvider.closeConnection(connection);
   }
 
   @Override
   public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
      releaseAnyConnection(connection);
   }
}
```
SchemaResolver.java
Code:
```
public class SchemaResolver implements CurrentTenantIdentifierResolver {
    
   @Override
   public String resolveCurrentTenantIdentifier() {
      return "db1"; //TODO: Implement service to identify tenant like: userService.getCurrentlyAuthUser().getTenantId();
   }
 
   @Override
   public boolean validateExistingCurrentSessions() {
      return false;
   }
}
```
RegiaterController.java
Code:
```
@Controller
@RequestMapping(value="/login")
public class RegisterController 
{
   static final Logger m_oLogger = Logger.getLogger(RegisterController.class);
   @RequestMapping(method = RequestMethod.POST, headers = {"Content-type=application/json"})
   @ResponseBody
    public boolean login(@RequestBody RegisterData oData) 
   {
      boolean bIsSaved = false;
      PropertyConfigurator.configure("C:\\Program Files (x86)\\Apache Software Foundation\\Tomcat 7.0\\webapps\\register\\WEB-INF\\classes\\com\\techmust\\resource\\log4j.properties");
      SessionFactory oSessionFactory = HibernateUtil.buildSessionFactory();
      SessionBuilder oSessionBuilder = oSessionFactory.withOptions();
      SessionBuilder oBuilder = oSessionBuilder.tenantIdentifier("db1");
      Session oSession = oBuilder.openSession();
//      Session oSession = oSessionFactory.openSession();
      m_oLogger.info("login [IN] : " + oSession);
      
      try
      {
         if(!(oData.getStrPassword().equals("") && oData.getStrUserName().equals("")))
         {
            
            Transaction oTransaction = oSession.beginTransaction();
            System.out.println(oData.getStrUserName());
            System.out.println(oData.getStrPassword());
            System.out.println(oSession);
            oSession.save(oData);
            oTransaction.commit();
            bIsSaved = oTransaction.wasCommitted();
            oSession.flush();
         }
      }
      catch (Exception oException)
      {
         m_oLogger.error ("login - oException : " + oException);
      }
      return bIsSaved;
   }
}
```
Please find the Log
Code:
```
Caused by: java.lang.NullPointerException
   at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$MultiTenantConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcServicesImpl.java:271)
   at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:119)
   at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
   at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
   at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
   at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:71)
   at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2270)
   at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2266)
   at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1735)
   at com.techmust.HibernateUtil.buildSessionFactory(HibernateUtil.java:36)
   ... 37 more
```
The above code is for web application.
Below is the java application code which uses same hibernate files as above and gives the desired output
Code:
```
public class RegisterController 
{
   public static void main(String args[]){
      RegisterControllerMethod oController = new RegisterControllerMethod();
      oController.getSampleDetails("db1");
      oController.getSampleDetails("db2");
   }
}
class RegisterControllerMethod {
   static final Logger m_oLogger = Logger.getLogger(RegisterController.class);
   public void getSampleDetails(String strSchema)
   {
      PropertyConfigurator.configure("E:\\Development\\javaprojects\\Register_Server\\src\\com\\techmust\\resource\\log4j.properties");
      Session oSession = HibernateUtil.buildSessionFactory().withOptions().tenantIdentifier(strSchema).openSession();
      m_oLogger.info("login [IN] : " + oSession);
      RegisterData oData = new RegisterData();
      oData.setStrPassword("admin");
      oData.setStrUserName("admin");
      
      try
      {
            
         Transaction oTransaction = oSession.beginTransaction();
         System.out.println(oSession);
         oSession.save(oData);
         oTransaction.commit();
         oTransaction.wasCommitted();
         oSession.flush();
      }
      catch (Exception oException)
      {
         m_oLogger.error ("login - oException : " + oException);
      }
      
   }
   
}
```
Please guide us on running the above code as web application.