-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Multi-tenancy, Webservice, EJB, JPA, JBoss problem
PostPosted: Fri Mar 08, 2013 5:16 am 
Newbie

Joined: Fri Mar 08, 2013 3:41 am
Posts: 2
Hi,

I try to apply hibernate multi-tenancy on our current project, that had been implemented with Webservice, EJB, JPA and JBoss 7.1.1 Final.
And I got a exception when I just enable my services on JBoss by administrator tool:

Code:
14:16:26,320 INFO  [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service thread 1-2) register: jboss.ws:context=test_ejb,endpoint=ContactWebService
14:16:26,320 INFO  [org.jboss.as.jpa] (MSC service thread 1-4) JBAS011402: Starting Persistence Unit Service 'test_ear.ear/test_service-1.01.28.jar#xcrmPU'
14:16:26,320 INFO  [org.hibernate.ejb.Ejb3Configuration] (MSC service thread 1-4) HHH000204: Processing PersistenceUnitInfo [
   name: xcrmPU
   ...]
14:16:26,320 INFO  [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service thread 1-3) register: jboss.ws:context=test_ejb,endpoint=StudyPeriodWebService
14:16:26,351 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed to start service jboss.persistenceunit."test_ear.ear/test_service-1.01.28.jar#xcrmPU": org.jboss.msc.service.StartException in service jboss.persistenceunit."test_ear.ear/test_service-1.01.28.jar#xcrmPU": Failed to start service
   at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_30]
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_30]
   at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_30]
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 org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:84)
   at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
   at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889)
   at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
   at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:162)
   at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.start(PersistenceUnitServiceImpl.java:85)
   at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
   at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
   ... 3 more


What I see the JBoss didn't call my DatabaseBasedMultiTenantConnectionProvider instance, it seem it uses the default MultiTenantConnectionProvider in time it actives my ejb services (I guess).
My implementation similar to this https://hibernate.onjira.com/browse/HHH-7659 (please by pass the bug, refer the attach code, I try to implement same structure)
Here is what I have done (Sorry for long content, I don't know how to attach files):
- Config persistence.xml like this:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="xcrmPU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>             
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <shared-cache-mode>NONE</shared-cache-mode>
        <properties>
           <!-- property name="hibernate.connection.datasource" value="java:jboss/xlinedta001_TestMySql"/-->
           <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.format_sql" value="false"/>     
            <!-- property name="transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/-->
            <property name="hibernate.connection.autocommit" value="true"/>     
                   
            <property name="hibernate.multiTenancy" value="DATABASE"/>
            <property name="hibernate.tenant_identifier_resolver" value="DatabaseBasedMultiTenantResolver"/>
            <property name="hibernate.multi_tenant_connection_provider" value="DatabaseBasedMultiTenantConnectionProvider"/>
            <!-- (for glassfish) property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup"/ -->
            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>                                                                               
        </properties>
    </persistence-unit>
</persistence>

- Implement DatabaseBasedMultiTenantResolver, get the user Principal from session context:
Code:
public class DatabaseBasedMultiTenantResolver implements CurrentTenantIdentifierResolver {
   private static Log log = LogFactory.getLog(DatabaseBasedMultiTenantResolver.class);
   
    @Override
    public String resolveCurrentTenantIdentifier() {
       log.info("resolveCurrentTenantIdentifier: ");
        try {
           SessionContext context = null;
           try {
                 InitialContext ic = new InitialContext();
                 context =
                     (SessionContext) ic.lookup("java:comp/EJBContext");
                 log.info("Look up EJBContext by standard name: " + context);
               } catch (NamingException ex) {
                 throw new IllegalStateException(ex);
               }
                               
            String userName = context.getCallerPrincipal().getName();           
            log.info("Look up user name: " + userName);
            return userName;
        } catch (Throwable e) {
           log.error("error lookup environment from session context");
        }

        return "TestMySql";
    }

    @Override
    public boolean validateExistingCurrentSessions() {
        return false;
    }
}

- Implement DatabaseBasedMultiTenantConnectionProvider:
Code:
public class DatabaseBasedMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider implements MultiTenantConnectionProvider, ServiceRegistryAwareService {
   private static Log log = LogFactory.getLog(DatabaseBasedMultiTenantConnectionProvider.class);
      private static final long serialVersionUID = -4491110199823075559L;
      
   private Map<String, C3P0ConnectionProvider> providers = new HashMap<String, C3P0ConnectionProvider>();
    private ServiceRegistryImplementor serviceRegistry;

    @Override
    public void injectServices(ServiceRegistryImplementor serviceRegistry) {
        this.serviceRegistry = serviceRegistry;
    }

    @Override
    protected ConnectionProvider getAnyConnectionProvider() {
        return createDefaultConnectionProvider();
    }
    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
       log.info("createDefaultConnectionProvider: get connection");
       return super.getConnection(tenantIdentifier);
    }

    private ConnectionProvider createDefaultConnectionProvider() {
       log.info("createDefaultConnectionProvider: ");
       Map<String, String> lSettings = new HashMap<String, String>();
       lSettings.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
        lSettings.put("hibernate.connection.url", "jdbc:mysql://192.168.1.10:3306/defaultDB?autoReconnect=true");
        lSettings.put("hibernate.connection.username", "root");
        lSettings.put("hibernate.connection.password", "dbavn");
        lSettings.put("hibernate.c3p0.min_size", "5");
        lSettings.put("hibernate.c3p0.max_size", "20");
        lSettings.put("hibernate.c3p0.timeout", "1800");
        lSettings.put("hibernate.c3p0.max_statements", "50");
        lSettings.put("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
        lSettings.put("hibernate.connection.autocommit", "true");       
        C3P0ConnectionProvider connectionProvider = new C3P0ConnectionProvider();
        connectionProvider.injectServices(serviceRegistry);
        connectionProvider.configure(lSettings);
        return connectionProvider;

    }

    /**
     *
     * @param tenantIdentifier
     * @return
     */
    @Override
    protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
       log.info("selectConnectionProvider: " + tenantIdentifier);
        if (!providers.containsKey(tenantIdentifier)) {
            Map<String, String> lSettings = new HashMap<String, String>();

            if (tenantIdentifier.equalsIgnoreCase("TestMySql")) {
               lSettings.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
                lSettings.put("hibernate.connection.url", "jdbc:mysql://192.168.1.11:3306/db001?autoReconnect=true");
                lSettings.put("hibernate.connection.username", "root");
                lSettings.put("hibernate.connection.password", "dbavn");
                lSettings.put("hibernate.c3p0.min_size", "5");
                lSettings.put("hibernate.c3p0.max_size", "20");
                lSettings.put("hibernate.c3p0.timeout", "1800");
                lSettings.put("hibernate.c3p0.max_statements", "50");
                lSettings.put("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
                lSettings.put("hibernate.connection.autocommit", "true");
            } else if (tenantIdentifier.equalsIgnoreCase("TestSqlServer")) {
               lSettings.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
                lSettings.put("hibernate.connection.url", "jdbc:sqlserver://192.168.1.12;databaseName=db001");
                lSettings.put("hibernate.connection.username", "admin");
                lSettings.put("hibernate.connection.password", "admin");
                lSettings.put("hibernate.c3p0.min_size", "5");
                lSettings.put("hibernate.c3p0.max_size", "20");
                lSettings.put("hibernate.c3p0.timeout", "1800");
                lSettings.put("hibernate.c3p0.max_statements", "50");
                lSettings.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
                lSettings.put("hibernate.connection.autocommit", "true");
            } else if (tenantIdentifier.equalsIgnoreCase("TestOracle")) {
               lSettings.put("hibernate.connection.driver_class", "oracle.jdbc.driver.OracleDriver");
                lSettings.put("hibernate.connection.url", "jdbc:oracle:thin:@192.168.1.13:1521:xe");
                lSettings.put("hibernate.connection.username", "db001");
                lSettings.put("hibernate.connection.password", "dbavn");
                lSettings.put("hibernate.c3p0.min_size", "5");
                lSettings.put("hibernate.c3p0.max_size", "20");
                lSettings.put("hibernate.c3p0.timeout", "1800");
                lSettings.put("hibernate.c3p0.max_statements", "50");
                lSettings.put("hibernate.dialect", "org.hibernate.dialect.Oracle9Dialect");
                lSettings.put("hibernate.connection.autocommit", "true");
            } else {
               return this.createDefaultConnectionProvider();
            }

            C3P0ConnectionProvider connectionProvider = new C3P0ConnectionProvider();
            connectionProvider.injectServices(serviceRegistry);           
            connectionProvider.configure(lSettings);
            providers.put(tenantIdentifier, connectionProvider);
        }
        return providers.get(tenantIdentifier);
    }
}

- The all web service methods have to programmatic log in a user like:
Code:
UsernamePasswordHandler handler = new UsernamePasswordHandler(environment, "");
      LoginContext lc = null;
      try   {
         lc = new LoginContext("module-name", handler);
         lc.login();

         // Everything from here on is automatically associated with
         // the Subject authenticated by the login
      } catch (Exception e) {
         // handle exception
         throw new XcrmEjbException("TEST_TENANCY", e.getMessage());
      }

- Update the configuration xml to use the latest hibernate on jboss:
+ The jboss-deployment-structure.xml file:
Code:
<jboss-deployment-structure>
    <ear-subdeployments-isolated>true</ear-subdeployments-isolated>
    <deployment>
        <!-- Exclusions allow you to prevent the server from automatically adding some dependencies     -->
        <exclusions>
            <module name="org.hibernate"/>           
        </exclusions>
    </deployment>
</jboss-deployment-structure>

+ The jboss-app.xml:
Code:
<jboss-app>   
<loader-repository> 
   org.myapp:loader=SomeClassloader 
   <loader-repository-config> 
      java2ParentDelegation=false 
   </loader-repository-config> 
</loader-repository>       
</jboss-app> 

+ The login-config.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
   <application-policy name="test">
      <authentication>
         <!-- Add this line to your login-config.xml to include the ClientLoginModule propogation -->     
         <login-module code="org.jboss.security.ClientLoginModule" flag="required" ></login-module>   
      </authentication>
   </application-policy>
</deployment>

+ The maven profile:
Code:
<profile>
         <id>glassfish</id>

         <dependencies>
            <dependency>
               <groupId>org.hibernate</groupId>
               <artifactId>hibernate-commons-annotations</artifactId>
               <version>3.2.0.Final</version>
               <type>jar</type>
               <scope>compile</scope>
            </dependency>

            <dependency>
               <groupId>org.hibernate</groupId>
               <artifactId>hibernate-entitymanager</artifactId>
               <version>4.2.0.CR1</version>
               <type>jar</type>
               <scope>compile</scope>
            </dependency>   
            
            <dependency>
               <groupId>org.hibernate</groupId>
               <artifactId>hibernate-c3p0</artifactId>
               <version>4.2.0.CR1</version>
               <type>jar</type>
               <scope>compile</scope>
            </dependency>
            
            <dependency>
               <groupId>org.jboss.logging</groupId>
               <artifactId>jboss-logging</artifactId>
               <version>3.1.0.CR1</version>
               <scope>compile</scope>
            </dependency>
            
            <dependency>
               <groupId>c3p0</groupId>
               <artifactId>c3p0</artifactId>
               <version>0.9.1.2</version>
               <scope>compile</scope>
            </dependency>

            <dependency>
               <groupId>javassist</groupId>
               <artifactId>javassist</artifactId>
               <version>3.12.1.GA</version>
               <type>jar</type>
               <scope>compile</scope>
            </dependency>

            <dependency>
               <groupId>antlr</groupId>
               <artifactId>antlr</artifactId>
               <version>2.7.7</version>
               <type>jar</type>
               <scope>compile</scope>
            </dependency>
            <dependency>
               <groupId>dom4j</groupId>
               <artifactId>dom4j</artifactId>
               <version>1.6.1</version>
               <type>jar</type>
            </dependency>

         </dependencies>
         <build>
            <plugins>
               <plugin>
                  <artifactId>maven-ear-plugin</artifactId>
                  <version>2.6</version>
                  <configuration>
                     <displayName>test_ear</displayName>
                     <includeInApplicationXml>true</includeInApplicationXml>
                     <modules>
                        <ejbModule>
                           <groupId>ch.xpertline</groupId>
                           <artifactId>test_service</artifactId>
                        </ejbModule>
                        <jarModule>
                           <groupId>commons-lang</groupId>
                           <artifactId>commons-lang</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>org.slf4j</groupId>
                           <artifactId>slf4j-api</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>javassist</groupId>
                           <artifactId>javassist</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>log4j</groupId>
                           <artifactId>log4j</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>antlr</groupId>
                           <artifactId>antlr</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>org.slf4j</groupId>
                           <artifactId>slf4j-log4j12</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>commons-logging</groupId>
                           <artifactId>commons-logging</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>commons-collections</groupId>
                           <artifactId>commons-collections</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>org.hibernate</groupId>
                           <artifactId>hibernate-entitymanager</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>
                        
                        <jarModule>
                           <groupId>org.hibernate</groupId>
                           <artifactId>hibernate-c3p0</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>
                        
                        <jarModule>
                           <groupId>org.jboss.logging</groupId>
                           <artifactId>jboss-logging</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>
                           
                           <jarModule>
                           <groupId>c3p0</groupId>
                           <artifactId>c3p0</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>
                              
                        <jarModule>
                           <groupId>org.hibernate.javax.persistence</groupId>
                           <artifactId>hibernate-jpa-2.0-api</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>org.hibernate</groupId>
                           <artifactId>hibernate-validator</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>org.hibernate</groupId>
                           <artifactId>hibernate-commons-annotations</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>org.hibernate</groupId>
                           <artifactId>hibernate-core</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>dom4j</groupId>
                           <artifactId>dom4j</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>

                        <jarModule>
                           <groupId>commons-collections</groupId>
                           <artifactId>commons-collections</artifactId>
                           <bundleDir>lib</bundleDir>
                        </jarModule>
                     </modules>
                  </configuration>
               </plugin>

               <plugin>
                  <groupId>org.glassfish.maven.plugin</groupId>
                  <artifactId>maven-glassfish-plugin</artifactId>
                  <version>2.1</version>
                  <configuration>
                     <glassfishDirectory>${glassfish.home}</glassfishDirectory>
                     <user>${domain.username}</user>
                     <adminPassword>${domain.password}</adminPassword>
                     <autoCreate>true</autoCreate>
                     <debug>true</debug>
                     <echo>false</echo>
                     <terse>true</terse>
                     <skip>${test.int.skip}</skip>
                     <components>
                        <component>
                           <name>${project.artifactId}</name>
                           <artifact>${project.build.directory}/${project.build.finalName}.ear</artifact>
                        </component>
                     </components>
                  </configuration>
               </plugin>


I don't know JBoss a lot, so all configurations I search on Internet, not sure they are correct.

Thank you!


Top
 Profile  
 
 Post subject: Re: Multi-tenancy, Webservice, EJB, JPA, JBoss problem
PostPosted: Mon Apr 21, 2014 10:40 am 
Newbie

Joined: Mon Apr 21, 2014 10:36 am
Posts: 1
Hi,

I have also same requirement as you mentioned in the post. Did you resolve the issue?

Please reply me.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.