5 Replies Latest reply on Nov 4, 2011 11:46 AM by smarlow

    Migration from JBoss AS4 to 7 leads to problem with Hibernate

    t.b

      Hi,

       

      currently we're still runing JBoss 4.2.2 on production but would like to upgrade to a much more recent version. For our projects we're actually using JBoss as a better servlet container, the projects contain their dependencies and implementations of EE features. They do run on plain tomcat on the developers' machines.

       

      Unfortunately I'm having trouble getting our most recent project to work on JBoss 7.0.2. It is based on JSF (MyFaces, Richfaces), JPA (Hibernate 3 in "JPA mode") and Spring 3. Also a generic DAO implementation (http://code.google.com/p/hibernate-generic-dao/) is involved. All dependencies and implementations are included in the *.war file, the same package runs fine on Tomcat 6 and JBoss 4.2.2.

       

      After some fiddling with the configuration to prevent JBoss from injecting Hibernate 4 - which seems to be incompatible with our Spring version - I've got it to deploy. The landing page, containing JSF/Richfaces but no database content, renders fine. When I try to login or otherwise to access the database I get an Exception.

       

       

      java.lang.NullPointerException
       org.hibernate.impl.SessionFactoryImpl.getClassMetadata(SessionFactoryImpl.java:807)
       com.googlecode.genericdao.search.hibernate.HibernateMetadataUtil.get(HibernateMetadataUtil.java:92)
       com.googlecode.genericdao.search.hibernate.HibernateMetadataUtil.get(HibernateMetadataUtil.java:103)
       com.googlecode.genericdao.search.BaseSearchProcessor.prepareValue(BaseSearchProcessor.java:708)
       com.googlecode.genericdao.search.BaseSearchProcessor.filterToQL(BaseSearchProcessor.java:454)
       com.googlecode.genericdao.search.BaseSearchProcessor.generateWhereClause(BaseSearchProcessor.java:414)
       com.googlecode.genericdao.search.BaseSearchProcessor.generateQL(BaseSearchProcessor.java:111)
       com.googlecode.genericdao.search.jpa.JPASearchProcessor.searchUnique(JPASearchProcessor.java:189)
       com.googlecode.genericdao.dao.jpa.JPABaseDAO._searchUnique(JPABaseDAO.java:434)
       com.googlecode.genericdao.dao.jpa.GenericDAOImpl.searchUnique(GenericDAOImpl.java:137)
       de.motionet.internal.rhylia.facade.user.DefaultUserFacade.load(DefaultUserFacade.java:217)
       de.motionet.internal.rhylia.facade.user.DefaultUserFacade.loadUserByUsername(DefaultUserFacade.java:306)
       sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       ...
      

       

      From what I can see in the code of the genericdao implementation this means that SessionFactory.getClassMetadata must have returned null for the entity classes. I am sure that Hibernate finds and knows my @Entity classes since there are a lot of log entries during the deployment that tell me there was an error creating the table because it already exists.

       

      What I don't get is why the same code and almost the same configuration (I had to disable second level caching EhCache) works on JBoss AS 4.2.2 and on Tomcat 6 but not on JBoss AS 7.0.2 I have tried a nightly build, without success. This is the reason why I'm asking in the AS forum and not in the hibernate forum.

       

      Here's my persistence.xml:

       

      <?xml version="1.0" encoding="UTF-8"?>
      <persistence 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_1_0.xsd"
          version="1.0">
          <persistence-unit name="rhylia" transaction-type="RESOURCE_LOCAL">
              <provider>org.hibernate.ejb.HibernatePersistence</provider>
              <properties>
                  <property name="hibernate.hbm2ddl.auto" value="create" />
                  <property name="hibernate.archive.autodetection" value="class,hbm" />
                  <property name="hibernate.show_sql" value="false" />
                  <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
                  <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
                  <property name="hibernate.connection.password" value="xxxxx" />
                  <property name="hibernate.connection.url" value="jdbc:mysql://localhost/rhylia" />
                  <property name="hibernate.connection.username" value="xxxxx" />
                  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
                  <property name="hibernate.c3p0.min_size" value="5" />
                  <property name="hibernate.c3p0.max_size" value="20" />
                  <property name="hibernate.c3p0.timeout" value="300" />
                  <property name="hibernate.c3p0.max_statements" value="50" />
                  <property name="hibernate.c3p0.idle_test_period" value="3000" />
      
                  <!-- Hibernate EJB Caching -->
                  <!-- property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/-->
                     <property name="hibernate.cache.use_second_level_cache" value="false"/>
                  <property name="hibernate.cache.use_query_cache" value="true"/>
                  <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />
                  <property name="hibernate.cache.provider_configuration_file_resource_path" value="/ehcache.xml" />
                  <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
                  <property name="jboss.as.jpa.providerModule" value="hibernate3-bundled"/>
                  
              </properties>
          </persistence-unit>
      </persistence>
      

       

      Two changes made here are hibernate.cache.use_second_level_cache and adding jboss.as.jpa.providerModule. The file is included in the same jar as the entity classes.

       

      I know I'm supposed to let the app server handle database configuration for me and receive the connection from it. If this is absolutely necessary it would be an option, but I'd prefer to skip this step. At least for now.

       

      I added a jboss-deployment-structure.xml to exclude "org.hibernate" to prevent injecting version 4; I need 3.x for now.

       

       

      What am I doing wrong? How do I get this to work? Help would be very appreciated.

       

      Btw: is there a way to exclude implicit dependencies? Can I tell AS7 that I want it to handle a given *.war as a servlet container would, no matter what it autodetects in there?

       

      Greetings,

       

        Thomas

        • 1. Re: Migration from JBoss AS4 to 7 leads to problem with Hibernate
          smarlow

          Which version of Hibernate3 are you including?

           

          You might try enabling JPA TRACE logging but that is broken in AS 7.0.2.  So, you would have to download the nightly build from community.jboss.org/thread/167590.  Steps for enabling JPA TRACE are in https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide.

          • 2. Re: Migration from JBoss AS4 to 7 leads to problem with Hibernate
            t.b

            Thank you for your answer.

             

            I'd need to check which version was originally included, but an update to 3.6.8, the latest 3.x version, does not help.

             

            The trace log is ... interesting. I do not understand what exactly happens or why, this might be or not be normal.

             

            First it tells me, that it reads my config:

             

            10:06:51,459 INFO  [org.jboss.jpa] (MSC service thread 1-4) JBAS011401: Read persistence.xml for rhylia
            

             

            Then 56 times the following block appears:

             

            10:06:51,465 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) pu search for name 'null' inside of hubber.war
            10:06:51,465 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) findWithinDeployment check 'null' against pu 'rhylia'
            10:06:51,466 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) findWithinDeployment matched 'null' against pu 'rhylia'
            10:06:51,466 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) pu search found PersistenceUnitMetadataImpl(version=1.0) [
                name: rhylia
                jtaDataSource: null
                nonJtaDataSource: null
                transactionType: RESOURCE_LOCAL
                provider: org.hibernate.ejb.HibernatePersistence
                classes[
                ]
                packages[
                ]
                mappingFiles[
                ]
                jarFiles[
                ]
                validation-mode: AUTO
                shared-cache-mode: UNSPECIFIED
                properties[
                    hibernate.connection.password: rhylia
                    hibernate.c3p0.idle_test_period: 3000
                    hibernate.cache.use_second_level_cache: false
                    hibernate.show_sql: false
                    hibernate.c3p0.max_statements: 50
                    hibernate.c3p0.timeout: 300
                    hibernate.archive.autodetection: class,hbm
                    hibernate.hbm2ddl.auto: create
                    hibernate.cache.use_query_cache: true
                    jboss.as.jpa.providerModule: hibernate3-bundled
                    hibernate.c3p0.min_size: 5
                    hibernate.connection.username: rhylia
                    hibernate.connection.driver_class: com.mysql.jdbc.Driver
                    hibernate.cache.provider_class: org.hibernate.cache.EhCacheProvider
                    hibernate.c3p0.max_size: 20
                    hibernate.connection.provider_class: org.hibernate.connection.C3P0ConnectionProvider
                    hibernate.cache.provider_configuration_file_resource_path: /ehcache.xml
                    hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect
                    hibernate.connection.url: jdbc:mysql://localhost/rhylia
                ]]
            

             

            10:06:52,670 DEBUG [org.jboss.as.jpa] (MSC service thread 1-3) added javax.persistence.api, javaee.api, org.jboss.as.jpa, org.javassist dependencies to hubber.war
            10:06:52,671 DEBUG [org.jboss.as.jpa] (MSC service thread 1-3) rhylia is configured to use application supplied persistence provider
            10:06:53,897 DEBUG [org.jboss.as.jpa] (MSC service thread 1-3) Deployment has its own Persistence Provider class org.hibernate.ejb.HibernatePersistence 
            10:06:54,581 INFO  [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-3) JBAS010404: Deploying non-JDBC-compliant driver class com.mysql.jdbc.Driver (version 5.1)
            10:06:54,870 INFO  [org.jboss.jpa] (MSC service thread 1-2) JBAS011402: Starting Persistence Unit Service 'hubber.war#rhylia'
            

             

            Followed by a lot of lines where AnnotationBinder warns me that "Package not found or wo package-info.java".

             

            10:06:57,610 INFO  [org.hibernate.validator.util.Version] (MSC service thread 1-2) Hibernate Validator 4.2.0.Final
            10:06:59,171 INFO  [com.mchange.v2.log.MLog] (MSC service thread 1-2) MLog clients using java 1.4+ standard logging.
            10:06:59,368 INFO  [com.mchange.v2.c3p0.C3P0Registry] (MSC service thread 1-2) Initializing c3p0-0.9.1.2-motionet-1 [built 03-November-2011 
                13:51:39; debug? false; trace: 5]
            10:06:59,542 INFO  [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] (MSC service thread 1-2) Initializing c3p0 pool... 
                com.mchange.v2.c3p0.PoolBackedDataSource@71db27ca [ connectionPoolDataSource -> 
                com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@de524106 [ acquireIncrement -> 3, acquireRetryAttempts -> 30, 
                acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0,
                connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester,
                debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken ->
                z8kflt8juh2l2r15bdm4x|78f58a2a, idleConnectionTestPeriod -> 3000, initialPoolSize -> 5, maxAdministrativeTaskTime -> 0, maxConnectionAge
                -> 0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 50, maxStatementsPerConnection -> 0,
                minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@2f7fed80 [ description -> null, driverClass -> null,
                factoryClassLocation -> null, identityToken -> z8kflt8juh2l2r15bdm4x|49869a03, jdbcUrl -> jdbc:mysql://localhost/rhylia, properties ->
                {user=******, password=******, autocommit=true, release_mode=auto} ], preferredTestQuery -> SELECT 1 FROM DUAL;, propertyCycle -> 0,
                testConnectionOnCheckin -> false, testConnectionOnCheckout -> true, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies ->
                false; userOverrides: {} ], dataSourceName -> null, factoryClassLocation -> null, identityToken -> z8kflt8juh2l2r15bdm4x|2ac79769,
                numHelperThreads -> 3 ]
            

             

            Lots of messages like the following, including for the table associated with the entity involved in the exception in my first post.

             

            10:07:24,597 INFO  [stdout] (MSC service thread 1-2) [04.11.2011 10:07:24] ERROR  [SchemaExport] Unsuccessful: create table RH_Blobs 
               (BlobId bigint not null unique, Category varchar(16) not null, Size bigint not null, Type varchar(255) not null, primary key (BlobId)) ENGINE=InnoDB
            10:07:24,598 INFO  [stdout] (MSC service thread 1-2) [04.11.2011 10:07:24] ERROR  [SchemaExport] Table 'RH_Blobs' already exists
            

             

            Similar lines occur for the (named) foreign keys. They cannot be created because they already exist

             

            10:07:36,116 INFO  [stdout] (MSC service thread 1-2) [04.11.2011 10:07:36] WARN   [SessionFactoryImpl] JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()
            10:07:36,120 INFO  [stdout] (MSC service thread 1-2) [04.11.2011 10:07:36] WARN   [EhCacheProvider] Could not find configuration [org.hibernate.cache.UpdateTimestampsCache]; using defaults.
            10:07:36,150 INFO  [stdout] (MSC service thread 1-2) [04.11.2011 10:07:36] WARN   [EhCacheProvider] Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults.
            10:07:36,635 INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/hubber]] (MSC service thread 1-1) Initializing Spring root WebApplicationContext
            10:07:38,084 INFO  [stdout] (MSC service thread 1-1) [04.11.2011 10:07:38] ERROR  [SpringSecurityCoreVersion] Spring Major version '3' expected, but you are running with version: 7.1.0.Alpha2-SNAPSHOT. Please check your classpath for unwanted jar files.
            10:07:44,291 INFO  [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] (MSC service thread 1-1) Initializing c3p0 pool...
                com.mchange.v2.c3p0.PoolBackedDataSource@982abf94 [ connectionPoolDataSource -> 
               com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@775b5ebd [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay 
                -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0,
                connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester,
                debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken ->
                z8kflt8juh2l2r15bdm4x|da5a705, idleConnectionTestPeriod -> 3000, initialPoolSize -> 5, maxAdministrativeTaskTime -> 0, maxConnectionAge ->
                0, maxIdleTime -> 300, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 50, maxStatementsPerConnection -> 0,
                minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@2db47140 [ description -> null, driverClass -> null,
                factoryClassLocation -> null, identityToken -> z8kflt8juh2l2r15bdm4x|786c4ad7, jdbcUrl -> jdbc:mysql://localhost/rhylia, properties ->
                {user=******, password=******, autocommit=true, release_mode=auto} ], preferredTestQuery -> SELECT 1 FROM DUAL;, propertyCycle -> 0,
                testConnectionOnCheckin -> false, testConnectionOnCheckout -> true, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies ->
                false; userOverrides: {} ], dataSourceName -> null, factoryClassLocation -> null, identityToken -> z8kflt8juh2l2r15bdm4x|76784042,
                numHelperThreads -> 3 ]
            10:07:44,406 INFO  [stdout] (MSC service thread 1-1) [04.11.2011 10:07:44] WARN   [EhCacheProvider] Could not find configuration [org.hibernate.cache.UpdateTimestampsCache]; using defaults.
            10:07:44,415 INFO  [stdout] (MSC service thread 1-1) [04.11.2011 10:07:44] WARN   [EhCacheProvider] Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults.
            

             

            After that there are only some MyFaces INFO lines I already know and the exception on trying to access the DB.

             

             

            There are two points I don't understand. This might be normal or be the missing hint.

             

            First, the 56 repeats of the same block. But this matches the number of entity classes and they are not explicitly associated with a persistence unit. I guess that is what the log is trying to tell me.

             

            Second the apparently two initializations of C3P0. This might mean that the whole entity manager is initiated and most likely instantiated twice. This could explain why I see the entities recognised (tried table creation) but unknown when asking  the SessionFactory. What could lead to this and how do I prevent this?

             

            Greetings,

             

            Thomas

            • 3. Re: Migration from JBoss AS4 to 7 leads to problem with Hibernate
              smarlow

              The (56 times) repeated block (quoted below) corresponds to 56 @PersistenceContext or @PersistenceUnit injections into EntityManager or EntityManagerFactory variables (by the JPA container managed support in AS7).  The found (rhylia) persistence unit definition is also shown each time.  If your not using the EE container managed JPA support, you probably should disable it (since your not using it). 

               

              10:06:51,465 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) pu search for name 'null' inside of hubber.war
              10:06:51,465 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) findWithinDeployment check 'null' against pu 'rhylia'
              10:06:51,466 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) findWithinDeployment matched 'null' against pu 'rhylia'
              10:06:51,466 TRACE [org.jboss.as.jpa] (MSC service thread 1-4) pu search found PersistenceUnitMetadataImpl(version=1.0) [

              ...

               

               

              Try removing the EE container managed JPA support by deleting the following lines in as7/standalone/configuration/standalone.xml.  I don't think this is causing the problem you are experiencing but it will reduce the noise at least. 

               

              <extension module="org.jboss.as.jpa"/>

              .

              .

              .

               

              <subsystem xmlns="urn:jboss:domain:jpa:1.0">

                 <jpa default-datasource=""/>

              </subsystem>

               

               

              There were other posts about using Spring on AS7, that you probably should search for.  Also read http://community.jboss.org/blogs/mariusb/2011/07/13/spring-and-jboss-as7-part-1-getting-started

              • 4. Re: Migration from JBoss AS4 to 7 leads to problem with Hibernate
                t.b

                Hi,

                The (56 times) repeated block (quoted below) corresponds to 56 @PersistenceContext or @PersistenceUnit injections into EntityManager or EntityManagerFactory variables (by the JPA container managed support in AS7).

                Ah, I see. Yes, there are 56 occurences of @PersistenceContext public void setEntityManager(..) in the DAOs.

                 

                 

                Sometimes it just helps to ask the right question.

                 

                After my last reply I tried to find out why there were apparently two entity manager instances created. Apparently AS 7 provides one for me after seeing the persistence.xml. On the other hand one was explicitly instantiated via spring because that's what is needed in non-EE environments.

                 

                I added an persistence-unit-ref to web.xml and reconfigured spring to use jee:jndi-lookup instead of a LocalContainerEntityManagerFactoryBean. Now accessing the database seems to work.

                 

                Unfortunately somehow my database has been corrupted so my application still does not work as expected. But the exception now thrown indicates that some data can actually be read from the database, via JPA/Hibernate. Anyway that's another problem and hopefully not connected to this topic.

                 

                Try removing the EE container managed JPA support by deleting the following lines in as7/standalone/configuration/standalone.xml.  I don't think this is causing the problem you are experiencing but it will reduce the noise at least.

                I haven't tried this yet. I think this would deactivate JPA support for the whole AS not just for one deployment. Which would be fine for now, but future projects should really aim for full EE compatibility - needing JPA support then.  And as far as I can understand it my current (semi)working configuration uses the server's EE logic and behaviour and only overrides the implementation.

                 

                Thank you for your answers and your time.

                • 5. Re: Migration from JBoss AS4 to 7 leads to problem with Hibernate
                  smarlow

                  Try removing the EE container managed JPA support by deleting the following lines in as7/standalone/configuration/standalone.xml.  I don't think this is causing the problem you are experiencing but it will reduce the noise at least.

                  I haven't tried this yet. I think this would deactivate JPA support for the whole AS not just for one deployment. Which would be fine for now, but future projects should really aim for full EE compatibility - needing JPA support then.  And as far as I can understand it my current (semi)working configuration uses the server's EE logic and behaviour and only overrides the implementation.

                   

                  Thank you for your answers and your time.

                   

                  Yes, disabling JPA support for the whole AS, would be too disruptive but not as a learning exercise (to see what the impact is).  It sounds like you don't need to follow this path anyway.