Announcement Announcement Module
Collapse
No announcement yet.
Help:EJB3 entityManagerFactory or entityManager required Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help:EJB3 entityManagerFactory or entityManager required

    Hello,
    I've spent a week looking for an answer to my problem, and I have tried a lot of different Spring configurations, but finally I always get the same error message when I execute my EJB3 remote method.

    I'm using JPA with Hibernate 3 for my persistence layer, EJB3 for the services and all of this configured with Spring in a JBoss 4 AS enviroment. The problem, I think, is that no transaction exists, so when I tried to use my DAO from the EJB3 method, I get this error:
    Code:
    javax.ejb.EJBException: java.lang.IllegalArgumentException: entityManagerFactory or entityManager is required
    	at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:63)
    	at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
    	at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
    	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    	at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
    	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    	at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
    	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    	at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
    	at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106)
    	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    	at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
    	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    	at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
    	at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    	at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:278)
    	at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
    	at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
    	at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:734)
    	at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:560)
    	at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:369)
    	at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:165)
    When I execute my services jUnit tests, all its working OK. To do that, my jUnit extends from AbstractJpaTests and I execute my service method like a simple POJO. My applicationContext in this mode is the following:

    jUnit ApplicationContext.xml to do testing:
    HTML Code:
    <bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                 <property name="database" value="ORACLE"/>
    	<property name="showSql" value="true"/>
    </bean>
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    	<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    	<property name="url" value="jdbc:oracle:thin:@trinidad:1521:D03"/>
    		<property name="username" value="www"/>
    		<property name="password" value="www"/>
    </bean>
    
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    	<property name="dataSource" ref="dataSource"/>
    	<property name="jpaVendorAdapter" ref="jpaAdapter"/>
    	<property name="loadTimeWeaver">
         <bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/>
     	</property>
    </bean>
    
    <!-- Jpa Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
     </bean>
    	
    <bean id="transactionInterceptor"
          class="org.springframework.transaction.interceptor.TransactionInterceptor">
    	  <property name="transactionManager" ref="transactionManager" />
    	  <property name="transactionAttributeSource">
     <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
      </property>
    </bean>
    
    <bean id="daoAccessor" class="com.famasystems.dao.DAOAccessor" factory-method="getInstance">
    	<property name="factoryDao"  ref="jpaFactoryDao"/>
    </bean>
    	
    <bean id="jpaFactoryDao" class="com.famasystems.dao.jpa.FamaJpaFactoryDAO" autowire="default">
    	<property name="entityManagerFactory"  ref="entityManagerFactory"/>
    </bean>

    All the DAOs extends from JpaDaoSupport.
    My service ( Stateless EJB3 ) is:
    Code:
    @Stateless(name="ServicioCallejero")
    @Transactional
    @TransactionAttribute( TransactionAttributeType.REQUIRED )
    public class CallejeroBean implements CallejeroLocalBean,CallejeroRemoteBean {
      
    	public static final String LOCAL_JNDI_NNAME =  "ServicioCallejero/local";
    	public static final String REMOTE_JNDI_NNAME =  "ServicioCallejero/remote";
    	protected FamaFactoryDAO factoryDao = DAOAccessor.getInstance().getFactoryDao();
    	
    	private CallejeroFactoryDAO callejeroDao ;
    	
    	@PostConstruct
    	public void initialize() {
    		callejeroDao = factoryDao.getCallejeroFactoryDAO();
    		}
    	
    	@Transactional
    	public void savePais( Pais  pais ) {
    		PaisDAO dao = callejeroDao.getPaisDAO();
    		dao.save( pais );
    		dao.flush();
    	}
    }
    When I execute the line PaisDAO dao = callejeroDao.getPaisDAO();, my DAO, that has been previously injected with the entityManagerFactory from Spring,
    tries to start a transacational EntityManager, but is here where I'm always getting a null. I've checked that my entityManagerFactory is available and is not null,
    but the problem is later, when I execute the line 4 from the code below.
    Code:
    1: protected void initJpaDao( JpaDaoSupport jpaDao ) {
    2:		jpaDao.setEntityManagerFactory( entityManagerFactory );
    3:		EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager( entityManagerFactory ); //--> This always return null, but not in my unitTests!!
    4:		jpaDao.setEntityManager( em );
    5: }

    The ApplicationContext used in my service:
    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
    
    	
    	<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    		<property name="database" value="ORACLE"/>
    		<property name="showSql" value="true"/>
    	</bean>
    
    	
    	 <jee:jndi-lookup id="dataSource" jndi-name="java:/famaDB"/>
    	
    	
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    		<property name="dataSource" ref="dataSource"/>
    		<property name="persistenceUnitName" value="fama" />
    		<property name="jpaVendorAdapter" ref="jpaAdapter" />
    	</bean>
    
    	
    	<!-- Jpa Transaction Manager -->
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>
           
    	<bean id="daoAccessor" class="com.famasystems.dao.DAOAccessor" factory-method="getInstance">
    		<property name="factoryDao"  ref="jpaFactoryDao"/>
    	</bean>
    	
    	
    	<bean id="jpaFactoryDao" class="com.famasystems.dao.jpa.FamaJpaFactoryDAO" autowire="default">
    		<property name="entityManagerFactory"  ref="entityManagerFactory"/>
    	</bean>
    
      <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
      <tx:annotation-driven/>
        
    </beans>
    My pesistence.xml:
    HTML Code:
    <?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="fama" transaction-type="RESOURCE_LOCAL">
    		<provider>org.hibernate.ejb.HibernatePersistence</provider>
    
    		<!--  CALLEJERO -->
    		<class>com.famasystems.domain.callejero.Municipio</class>
    		<class>com.famasystems.domain.callejero.Localidad</class>
    		<class>com.famasystems.domain.callejero.TipoVia</class>
    		<class>com.famasystems.domain.callejero.Pais</class>
    		<class>
    			com.famasystems.domain.callejero.ComunidadAutonoma
    		</class>
    		<class>com.famasystems.domain.callejero.Via</class>
    		<class>com.famasystems.domain.callejero.Provincia</class>
    
    		</properties>
    	</persistence-unit>
    </persistence>
    Please, could somebody tell me what I'm doing wrong? Any clue will be really appreciated!

    Thank you very much in advance!

    Bests regards!

    Ivan Fontanals

  • #2
    JTA working..

    Hi,
    I have finally made it work, but with a JTA transaction.

    The error was in the creation of the EntityManager, because I was expecting to get a correct instance with the method EntityManagerFactoryUtils.getTransactionalEntityMa nager( entityManagerFactory ), but in the case the EntityManager was null, now I'm creating a new one with the method EntityManagerFactory.createEntityManager();.

    My application Context has been modified too. Now I have the following configuration:
    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
    	
    	<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    		<property name="database" value="ORACLE"/>
    		<property name="showSql" value="true"/>
    	</bean>
    
    	
    	 <jee:jndi-lookup id="dataSource" jndi-name="java:/famaDB"/>
    	 
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    		<property name="dataSource" ref="dataSource"/>
    		<property name="persistenceUnitName" value="fama" />
    		<property name="jpaVendorAdapter" ref="jpaAdapter" />
    		<property name="jpaProperties">
    			<props>
    					<prop key="show_sql">true</prop>
    					<prop key="hibernate.current_session_context_class">jta</prop>
    					<prop key="hibernate.session_factory_name">famaSessionFactory</prop>
    					<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
    					<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</prop>
    					</props>
    		</property>  
    	</bean>
    	
    	 <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    	<bean id="transactionManager"  class="org.springframework.transaction.jta.JtaTransactionManager"/>
    
    	
    	<bean id="daoAccessor" class="com.famasystems.dao.DAOAccessor" factory-method="getInstance">
    		<property name="factoryDao"  ref="jpaFactoryDao"/>
    	</bean>
    	
    	
    	<bean id="jpaFactoryDao" class="com.famasystems.dao.jpa.FamaJpaFactoryDAO" autowire="default">
    		<property name="entityManagerFactory"  ref="entityManagerFactory"/>
    	</bean>
    
    </beans>

    I hope this thread could help someone! I really have lost a lot of time.

    Thank you all!

    Ivan

    Comment


    • #3
      Ivan, is your Stateless EJB 3 injected in any of your components (a controller, etc) ? I'm having a tough time trying to inject a Stateless EJB 3 instance into a Spring controller (I'm using JBoss 4.2.0) as I'm getting an error which states something like "EJB home [...] has no no-arg create() method". I used the normal Spring JNDI locator ("org.springframework.ejb.access.SimpleRemoteState lessSessionProxyFactoryBean") and I've also tried some of the "jee:local-slsb" tags as well but with no success.

      Any help would be appreciated.

      Thanks.

      Comment

      Working...
      X