1 Reply Latest reply on Aug 26, 2011 2:25 PM by hmburgett

    JBoss 5.1 GA + JPA 1.0 + ServletContextListener - EntityManagerFactory injection

    hmburgett

      Hi,

       

      I've created a very simple web application consisting of ServletContextListener and 1 simple JPA Entity.  The web app gets deployed as the only WAR in an EAR.  When I start JBoss 5.1 GA with the EAR deployed, everything starts fine (no warnings or errors in the log) but any entities saved using the EntityManagerFactory injected into the ServletContextListener are not persisted to the database. 

       

      Within an Eclipse debugger, I see the EntityManagerFactory instance injected is org.jboss.jpa.injection.InjectedEntityManagerFactory and the EntityManager created from it is org.hibernate.ejb.EntityManagerImpl, but using these seem to do nothing with the database.

       

      Here are the details of my app:

       

      JBoss 5.1 GA

      JPA 1.0

      JDK 1.6

       

      ServletContextListener

       

      package com.hmb.sample;
      
      import javax.persistence.EntityManager;
      import javax.persistence.EntityManagerFactory;
      import javax.persistence.PersistenceUnit;
      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
      
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      
      public class ContextListener implements ServletContextListener
      {
          private static final Logger logger = LoggerFactory.getLogger( ContextListener.class );
      
          @PersistenceUnit( unitName = "mydb" )
          private EntityManagerFactory emf;
          
          public void contextInitialized( ServletContextEvent ctxEvent )
          {
              logger.info( "--> contextInitialized" );
              
              if ( emf == null )
              {
                  logger.error( "--> emf is null" );
              }
              
              EntityManager em = null;
              try
              {
                  em = emf.createEntityManager();
                  
                  if ( emf == null )
                  {
                      logger.error( "--> emf is null" );
                  }
                  
                  // save data to postgres
                  Sample s = new Sample();
                  s.setSomeText( "This is some sample text." );
                  
                  logger.info( "--> saving data" );
                  em.persist( s );
              }
              catch ( Exception e )
              {
                  logger.error( "Unexpected exception saving Sample.", e );
              }
              finally
              {
                  if ( em != null )
                  {
                      em.close();
                      logger.info( "--> em.close()" );
                  }
              }
      
          }
      
          public void contextDestroyed( ServletContextEvent ctxEvent )
          {
              logger.info( "--> contextDestroyed" );
          }
      
      }
      
      

       

      JPA Entity

       

      package com.hmb.sample;
      
      import java.io.Serializable;
      import javax.persistence.*;
      
      /**
       * The persistent class for the sample database table.
       * 
       */
      @Entity
      public class Sample implements Serializable
      {
          private static final long serialVersionUID = 1L;
      
          @Id
          @GeneratedValue( strategy = GenerationType.IDENTITY )
          private Integer id;
      
          @Column( name = "some_text" )
          private String someText;
      
          public Sample()
          {
          }
      
          public Integer getId()
          {
              return this.id;
          }
      
          public void setId( Integer id )
          {
              this.id = id;
          }
      
          public String getSomeText()
          {
              return this.someText;
          }
      
          public void setSomeText( String someText )
          {
              this.someText = someText;
          }
      
      }
      

       

      Persistence.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <persistence version="1.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_1_0.xsd">
      
          <persistence-unit name="mydb">
              <provider>org.hibernate.ejb.HibernatePersistence</provider>
              <jta-data-source>java:/PostgresDS</jta-data-source>
      
              <class>com.hmb.sample.Sample</class>
      
              <properties>
                  <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
                  <property name="jboss.entity.manager.factory.jndi.name"
                      value="java:/mydbEMF" />
              </properties>
      
          </persistence-unit>
      </persistence>
      

       

      JBoss Log Snippet

      2011-08-09 16:48:32,854 INFO  [org.jboss.jpa.deployment.PersistenceUnitDeployment] (HDScanner) Starting persistence unit persistence.unit:unitName=MyJpaSampleEAR.ear/MyJpaSampleWAR.war#mydb

      2011-08-09 16:48:33,305 INFO  [org.hibernate.cfg.annotations.Version] (HDScanner) Hibernate Annotations 3.4.0.GA

      2011-08-09 16:48:33,320 INFO  [org.hibernate.cfg.Environment] (HDScanner) Hibernate 3.3.1.GA

      2011-08-09 16:48:33,324 INFO  [org.hibernate.cfg.Environment] (HDScanner) hibernate.properties not found

      2011-08-09 16:48:33,327 INFO  [org.hibernate.cfg.Environment] (HDScanner) Bytecode provider name : javassist

      2011-08-09 16:48:33,333 INFO  [org.hibernate.cfg.Environment] (HDScanner) using JDK 1.4 java.sql.Timestamp handling

      2011-08-09 16:48:33,419 INFO  [org.hibernate.annotations.common.Version] (HDScanner) Hibernate Commons Annotations 3.1.0.GA

      2011-08-09 16:48:33,423 INFO  [org.hibernate.ejb.Version] (HDScanner) Hibernate EntityManager 3.4.0.GA

      2011-08-09 16:48:33,455 INFO  [org.hibernate.ejb.Ejb3Configuration] (HDScanner) Processing PersistenceUnitInfo [

          name: mydb

          ...]

      2011-08-09 16:48:33,470 WARN  [org.hibernate.ejb.Ejb3Configuration] (HDScanner) Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null.

      2011-08-09 16:48:33,535 INFO  [org.hibernate.cfg.AnnotationBinder] (HDScanner) Binding entity from annotated class: com.hmb.sample.Sample

      2011-08-09 16:48:33,583 INFO  [org.hibernate.cfg.annotations.EntityBinder] (HDScanner) Bind entity com.hmb.sample.Sample on table Sample

      2011-08-09 16:48:33,640 INFO  [org.hibernate.validator.Version] (HDScanner) Hibernate Validator 3.1.0.GA

      2011-08-09 16:48:33,688 INFO  [org.hibernate.cfg.search.HibernateSearchEventListenerRegister] (HDScanner) Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.

      2011-08-09 16:48:33,762 INFO  [org.hibernate.connection.ConnectionProviderFactory] (HDScanner) Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider

      2011-08-09 16:48:33,771 INFO  [org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider] (HDScanner) Using provided datasource

      2011-08-09 16:48:33,886 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) RDBMS: PostgreSQL, version: 8.4.7

      2011-08-09 16:48:33,886 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.4 JDBC4 (build 701)

      2011-08-09 16:48:33,909 INFO  [org.hibernate.dialect.Dialect] (HDScanner) Using dialect: org.hibernate.dialect.PostgreSQLDialect

      2011-08-09 16:48:33,915 INFO  [org.hibernate.transaction.TransactionFactoryFactory] (HDScanner) Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory

      2011-08-09 16:48:33,917 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner) instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup

      2011-08-09 16:48:33,920 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner) instantiated TransactionManagerLookup

      2011-08-09 16:48:33,920 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Automatic flush during beforeCompletion(): disabled

      2011-08-09 16:48:33,920 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Automatic session close at end of transaction: disabled

      2011-08-09 16:48:33,920 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC batch size: 15

      2011-08-09 16:48:33,920 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC batch updates for versioned data: disabled

      2011-08-09 16:48:33,921 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Scrollable result sets: enabled

      2011-08-09 16:48:33,921 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC3 getGeneratedKeys(): enabled

      2011-08-09 16:48:33,921 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Connection release mode: auto

      2011-08-09 16:48:33,922 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Default batch fetch size: 1

      2011-08-09 16:48:33,922 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Generate SQL with comments: disabled

      2011-08-09 16:48:33,922 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Order SQL updates by primary key: disabled

      2011-08-09 16:48:33,922 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Order SQL inserts for batching: disabled

      2011-08-09 16:48:33,922 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory

      2011-08-09 16:48:33,926 INFO  [org.hibernate.hql.ast.ASTQueryTranslatorFactory] (HDScanner) Using ASTQueryTranslatorFactory

      2011-08-09 16:48:33,926 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Query language substitutions: {}

      2011-08-09 16:48:33,926 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JPA-QL strict compliance: enabled

      2011-08-09 16:48:33,926 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Second-level cache: enabled

      2011-08-09 16:48:33,926 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Query cache: disabled

      2011-08-09 16:48:33,934 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge

      2011-08-09 16:48:33,935 INFO  [org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge] (HDScanner) Cache provider: org.hibernate.cache.HashtableCacheProvider

      2011-08-09 16:48:33,937 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Optimize cache for minimal puts: disabled

      2011-08-09 16:48:33,937 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Cache region prefix: persistence.unit:unitName=MyJpaSampleEAR.ear/MyJpaSampleWAR.war#mydb

      2011-08-09 16:48:33,937 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Structured second-level cache entries: disabled

      2011-08-09 16:48:33,945 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Statistics: disabled

      2011-08-09 16:48:33,945 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Deleted entity synthetic identifier rollback: disabled

      2011-08-09 16:48:33,946 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Default entity-mode: pojo

      2011-08-09 16:48:33,946 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Named query checking : enabled

      2011-08-09 16:48:33,997 INFO  [org.hibernate.impl.SessionFactoryImpl] (HDScanner) building session factory

      2011-08-09 16:48:34,184 INFO  [org.hibernate.impl.SessionFactoryObjectFactory] (HDScanner) Factory name: persistence.unit:unitName=MyJpaSampleEAR.ear/MyJpaSampleWAR.war#mydb

      2011-08-09 16:48:34,185 INFO  [org.hibernate.util.NamingHelper] (HDScanner) JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}

      2011-08-09 16:48:34,198 INFO  [org.hibernate.util.NamingHelper] (HDScanner) Creating subcontext: persistence.unit:unitName=MyJpaSampleEAR.ear

      2011-08-09 16:48:34,198 INFO  [org.hibernate.impl.SessionFactoryObjectFactory] (HDScanner) Bound factory to JNDI name: persistence.unit:unitName=MyJpaSampleEAR.ear/MyJpaSampleWAR.war#mydb

      2011-08-09 16:48:34,198 WARN  [org.hibernate.impl.SessionFactoryObjectFactory] (HDScanner) InitialContext did not implement EventContext

      2011-08-09 16:48:34,198 INFO  [org.hibernate.util.NamingHelper] (HDScanner) JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}

      2011-08-09 16:48:34,222 INFO  [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) deploy, ctxPath=/MyJpaSampleWAR

      2011-08-09 16:48:52,455 INFO  [com.hmb.sample.ContextListener] (HDScanner) --> contextInitialized

      2011-08-09 16:53:15,261 INFO  [com.hmb.sample.ContextListener] (HDScanner) --> saving data

      2011-08-09 16:53:27,933 INFO  [com.hmb.sample.ContextListener] (HDScanner) --> em.close()

       

      Any help in understanding what I'm missing would be much appreciated.

        • 1. Re: JBoss 5.1 GA + JPA 1.0 + ServletContextListener - EntityManagerFactory injection
          hmburgett

          Solution:  The EntityManagerFactory supplied by JBoss through injection in the ServletContentListener is application managed in terms of transactions, not container managed transactions.  This means the code must also get injected a UserTransaction that can be used to work with the EntityManager objects created.

           

          The following code sample solves the issue:

           

          package com.hmb.sample;

           

          import javax.annotation.Resource;

          import javax.persistence.EntityManager;

          import javax.persistence.EntityManagerFactory;

          import javax.persistence.PersistenceUnit;

          import javax.servlet.ServletContextEvent;

          import javax.servlet.ServletContextListener;

          import javax.transaction.UserTransaction;

           

          import org.slf4j.Logger;

          import org.slf4j.LoggerFactory;

           

           

          public class ContextListener implements ServletContextListener

          {

              private static final Logger logger = LoggerFactory.getLogger( ContextListener.class );

           

              @Resource

              private UserTransaction tx;

           

              @PersistenceUnit( unitName = "mydb" )

              private EntityManagerFactory emf;

           

              public void contextInitialized( ServletContextEvent ctxEvent )

              {

                  logger.info( "--> contextInitialized" );

           

                  if ( emf == null )

                  {

                      logger.error( "--> emf is null" );

                  }

           

                  EntityManager em = null;

                  try

                  {

                      tx.begin();

                      try

                      {

                          em = emf.createEntityManager();

                          if ( em == null )

                          {

                              logger.error( "--> em is null" );

                          }

           

                          // save data to postgres

                          Sample s = new Sample();

                          s.setSomeText( "This is some sample text." );

           

                          logger.info( "--> saving data" );

                          em.persist( s );

                      }

                      catch ( Exception e )

                      {

                          logger.error( "--> Unexpected exception persisting data." );

                      }

                      finally

                      {

                          if ( em != null )

                          {

                              em.close();

                              logger.info( "--> em.close()" );

                          }

                      }

           

                      tx.commit();

                  }

                  catch ( Exception e )

                  {

                      logger.error( "Unexpected exception saving Sample.", e );

                  }

           

              }

           

              public void contextDestroyed( ServletContextEvent ctxEvent )

              {

                  logger.info( "--> contextDestroyed" );

              }

           

          }