3 Replies Latest reply on Oct 14, 2010 6:48 AM by wdfink

    JBoss : persistence and EntityManager injection

    zecas

      Hi,

       

      I'm starting a small testing project from scratch, but I'm getting some trouble configuring JPA persistence ... I'll post some code fragments and hope someone can enlight me on the issue.

       

      I have an EAR, my-ear, and inside there is a single WAR, my-war. All definitions should be placed correctly, since I can make it to pick all settings, even those defined in "persistence.xml".

       

      my-war structure

       

      C:.
      |   index.jsp
      |
      +---META-INF
      |       MANIFEST.MF
      |
      \---WEB-INF
          |   faces-config.xml
          |   jboss-web.xml
          |   web.xml
          |
          +---classes
          |   +---com
          |   |   \---my
          |   |       \---package
          |   |               SimpleMessage.class
          |   |
          |   \---META-INF
          |           persistence.xml
          |
          \---lib
      

       

       

      web.xml

       

      <web-app ...>
          ...
          <resource-ref>
              <description>Datasource Connection</description>
              <res-ref-name>jdbc/MyDB</res-ref-name>
              <res-type>javax.sql.DataSource</res-type>
              <res-auth>Container</res-auth>
              <res-sharing-scope>Shareable</res-sharing-scope>
          </resource-ref>
      </web-app>
      

       

       

      jboss-web.xml

       

      <jboss-web>
          <resource-ref>
              <res-ref-name>jdbc/MyDB</res-ref-name>
              <jndi-name>java:/ds/MyDB</jndi-name>
          </resource-ref>
      </jboss-web>
      

       

       

      persistence.xml

       

      <persistence version="2.0"
          xmlns="http://java.sun.com/xml/ns/persistence"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <persistence-unit name="punit">
              <jta-data-source>java:jdbc/MyDB</jta-data-source>
          </persistence-unit>
      </persistence>
      

       

       

      My Java code has the following class:

       

      SimpleMessage.java

       

      package com.my.package; 
      import javax.persistence.PersistenceContext;
      public class SimpleMessage {
          @PersistenceContext
          private EntityManager em;
          @PersistenceUnit(name="punit")
          private EntityManagerFactory emf;
          public void something() {
              if( em!=null ) {
                  System.out.println("EntityManager Available!");
              } else {
                  System.out.println("EntityManager is NULL!");
              }
              if( emf!=null ) {
                  System.out.println("EntityManagerFactory Available!");
              } else {
                  System.out.println("EntityManagerFactory is NULL!");
              }
          }
      } 
      

       

       

      I intend to test just this ... a simple basic class where I inject the manager instance. The class is not an EJB class, just an basic injected class.

       

      When deploying, I get the following result:

       

      2010-10-13 14:09:55,197 INFO [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) deploy, ctxPath=/my-war
      2010-10-13 14:09:55,213 ERROR [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) ENC setup failed
      java.lang.NullPointerException
       at org.jboss.injection.PersistenceUnitHandler.getManagedEntityManagerFactory(PersistenceUnitHandler.java:149)
       at org.jboss.injection.PcEncInjector.inject(PcEncInjector.java:76)
       at org.jboss.web.tomcat.service.TomcatInjectionContainer.populateEnc(TomcatInjectionContainer.java:482)
      

       

       

      However, if in "persistence.xml" I instead define the datasource reference as "java:ds/MyDB" (datasource name definition on JBoss), I obtain the following result:

       

      2010-10-13 14:15:20,552 INFO  [org.jboss.jpa.deployment.PersistenceUnitDeployment] (HDScanner)  Starting persistence unit  persistence.unit:unitName=my-ear-1.0.0.ear/my-war-1.0.0.war#punit
      2010-10-13 14:15:20,552 INFO [org.hibernate.ejb.Ejb3Configuration] (HDScanner) Processing PersistenceUnitInfo [
       name: punit
       ...]
      2010-10-13  14:15:20,552 WARN [org.hibernate.ejb.Ejb3Configuration] (HDScanner)  Persistence provider caller does not implement the EJB3 spec correctly.  PersistenceUnitInfo.getNewTempClassLoader() is null.
      2010-10-13  14:15:20,568 INFO  [org.hibernate.cfg.search.HibernateSearchEventListenerRegister]  (HDScanner) Unable to find  org.hibernate.search.event.FullTextIndexEventListener on the classpath.  Hibernate Search is not enabled.
      2010-10-13 14:15:20,568 INFO  [org.hibernate.connection.ConnectionProviderFactory] (HDScanner)  Initializing connection provider:  org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
      2010-10-13  14:15:20,568 INFO  [org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider]  (HDScanner) Using provided datasource
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) RDBMS: MySQL, version: 5.1.41-3ubuntu12.6
      2010-10-13  14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC  driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1.10 (  Revision: ${svn.Revision} )
      2010-10-13 14:15:20,568 INFO [org.hibernate.dialect.Dialect] (HDScanner) Using dialect: org.hibernate.dialect.MySQLDialect
      2010-10-13  14:15:20,568 INFO [org.hibernate.transaction.TransactionFactoryFactory]  (HDScanner) Transaction strategy:  org.hibernate.ejb.transaction.JoinableCMTTransactionFactory
      2010-10-13  14:15:20,568 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner)  instantiating TransactionManagerLookup:  org.hibernate.transaction.JBossTransactionManagerLookup
      2010-10-13  14:15:20,568 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner)  instantiated TransactionManagerLookup
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Automatic flush during beforeCompletion(): disabled
      2010-10-13  14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner)  Automatic session close at end of transaction: disabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC batch size: 15
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC batch updates for versioned data: disabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Scrollable result sets: enabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC3 getGeneratedKeys(): enabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Connection release mode: auto
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Maximum outer join fetch depth: 2
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Default batch fetch size: 1
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Generate SQL with comments: disabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Order SQL updates by primary key: disabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Order SQL inserts for batching: disabled
      2010-10-13  14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Query  translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
      2010-10-13 14:15:20,568 INFO [org.hibernate.hql.ast.ASTQueryTranslatorFactory] (HDScanner) Using ASTQueryTranslatorFactory
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Query language substitutions: {}
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) JPA-QL strict compliance: enabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Second-level cache: enabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Query cache: disabled
      2010-10-13  14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Cache  region factory :  org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
      2010-10-13  14:15:20,568 INFO  [org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge]  (HDScanner) Cache provider: org.hibernate.cache.HashtableCacheProvider
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Optimize cache for minimal puts: disabled
      2010-10-13  14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Cache  region prefix:  persistence.unit:unitName=my-ear-1.0.0.ear/my-war-1.0.0.war#punit
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Structured second-level cache entries: disabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Statistics: disabled
      2010-10-13  14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner)  Deleted entity synthetic identifier rollback: disabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Default entity-mode: pojo
      2010-10-13 14:15:20,568 INFO [org.hibernate.cfg.SettingsFactory] (HDScanner) Named query checking : enabled
      2010-10-13 14:15:20,568 INFO [org.hibernate.impl.SessionFactoryImpl] (HDScanner) building session factory
      2010-10-13  14:15:20,568 INFO [org.hibernate.impl.SessionFactoryObjectFactory]  (HDScanner) Factory name:  persistence.unit:unitName=my-ear-1.0.0.ear/my-war-1.0.0.war#punit
      2010-10-13  14:15:20,568 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}
      2010-10-13  14:15:20,584 INFO [org.hibernate.impl.SessionFactoryObjectFactory]  (HDScanner) Bound factory to JNDI name:  persistence.unit:unitName=my-ear-1.0.0.ear/my-war-1.0.0.war#punit
      2010-10-13  14:15:20,584 WARN [org.hibernate.impl.SessionFactoryObjectFactory]  (HDScanner) InitialContext did not implement EventContext
      2010-10-13  14:15:20,584 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}
      2010-10-13 14:15:20,724 INFO [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) deploy, ctxPath=/my-war
      2010-10-13  14:15:20,755 INFO [javax.enterprise.resource.webcontainer.jsf.config]  (HDScanner) Initializing Mojarra (1.2_12-b01-FCS) for context '/my-war'  
      2010-10-13 14:15:20,896 ERROR [STDERR] (HDScanner) SLF4J: Class path contains multiple SLF4J bindings.
      2010-10-13  14:15:20,896 ERROR [STDERR] (HDScanner) SLF4J: Found binding in  [vfszip:/C:/Program  Files/Java/jboss-5.1.0.GA/common/lib/slf4j-jboss-logging.jar/org/slf4j/impl/StaticLoggerBinder.class]
      2010-10-13  14:15:20,896 ERROR [STDERR] (HDScanner) SLF4J: Found binding in  [vfszip:/C:/Program  Files/Java/jboss-5.1.0.GA/server/default/deploy/my-ear-1.0.0.ear/logback-classic-0.9.20.jar/org/slf4j/impl/StaticLoggerBinder.class]
      2010-10-13  14:15:20,912 ERROR [STDERR] (HDScanner) SLF4J: See  http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

       

       

      So my questions are:

       

      1# After invoking "SimpleMessage.something();" (using the second option "java:ds/MyDB" in "persistence.xml") I receive the following output:

       

      EntityManager is NULL!
      EntityManagerFactory is NULL!
      

       

      So no injection happened ... shouldn't it occur? what happened?

       


      2# I was assuming that "web.xml" defines the JNDI to be used inside my webapp, then "jboss-web.xml" would map that name into the internall JNDI defined in JBoss.

       

      In this case for JBoss usage, if changing to IBM WebSphere I would use another mapping config file.

       

      BUT ... I was also assuming that "persistence.xml" would define the JNDI that is defined in "web.xml" ... and not the one defined in application server level ... so I would get an abstraction from whichever server I'll deploy my project into.

       

      Shouldn't this be working like that? What am I doing wrong?

       

       

      Any help would be appreciated ... I really need to understand and put this to work ...

       

      Thanks.

        • 1. Re: JBoss : persistence and EntityManager injection
          wdfink

          For me it is unclear how you call the method something.

          Injection is nothing magic, the container must have a chance to do it.

          • 2. Re: JBoss : persistence and EntityManager injection
            zecas


            Wolf-Dieter Fink wrote:

             

            For me it is unclear how you call the method something.

            Injection is nothing magic, the container must have a chance to do it.

             

            First of all, Thanks for the help.

             

            I'm invoking the method in a servlet context listener defined in "web.xml".

             

            During the listener execution, I do something like:

             

            SimpleMessage sm = new SimpleMessage();
            sm.something();
            

             

             

            If I inject the EntityManagerFactory in the listener class, it is successfully instantiated and available (not NULL), but inside that class, I'm not getting it with a value other than NULL.

             

            Since I'm invoking the class from within a listener, which is inside the container, I was hoping (and testing) to get it to work ... to avoid having to pass it to the underlying class I'm invoking, and that will do the work.

             

            (Understanding this behaviour will help to clarify some doubts I'm having for some time.)

             

             

            Thanks.

            • 3. Re: JBoss : persistence and EntityManager injection
              wdfink

              As I said before, "nothing magic, the container do the work".

              This mean, if you are inside your servlet, the container analyse your servlet, inject the annotated fields and invoke the servlet method.

              If you instanciate a class by yourself, the container is not within the chain.

              With the next generation of JEE the scope of injection will be extended, but im not sure that code like your example will work.