Announcement Announcement Module
Collapse
No announcement yet.
getTransactionalEntityManager doesn't work with Spring DAOs when used with EJBs Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • getTransactionalEntityManager doesn't work with Spring DAOs when used with EJBs

    I'm using Spring 2.5.6 and EJB3 (JBoss 4.2 container) for our business layer. Stateless Session Beans are used to implement business logic and Spring based DAO are injected into EJBs using SpringBeanAutowiringInterceptor. EntityManager is injected into DAO using @PersistenceContext annotation.
    Spring creates new entitymanager for each DAO method irrespective the method is transactional or non-transactional and closes the entityManager when the method returns. So EntityManagerFactoryUtils.getTransactionalEntityMa nager always returns new entitymanager for every DAO method.
    Because of this behaviour, I am facing problem in few entityManager operations like "contains" and "flush" for the objects objects loaded, modified and updated in the same transaction. Let me give an example to explain my problem. Following is the EJB code:

    Code:
    // Get Portfolio entity object 
    Portfolio portfolio = portfolioDAO.findByUserIdAndInstrId(new BigDecimal(userId), instrId);
    
    // Update Portfolio entity object 
    portfolio.setTotalInstrOwned(newInstrOwned);
    
    // Update the changes to database
    portfolioDAO.merge(portfolio);
    Following is the merge method of PortfolioDAO:

    Code:
    @Transactional
    	public Portfolio merge(Portfolio entity) {
    		EntityManager em = getEntityManager();
    		if (!em.contains(entity)) {
    			entity = em.merge(entity);
    		}
    		em.flush();		
    		return entity;
    	}

    In this method "em.contains(entity))" always returns false, although entity is loaded and updated in the same transaction. This happens because Spring uses different persistent context (entitymanager) for 2 different DAO methods/calls.

    I want to know is there any way by which Spring use the same entitymanager for the entire JTA transaction, which may involve calls to multiple DAOs (behaviour should be same as container managed transaction scoped entity manager). Currently this is not working with Spring when used with EJBs.

    I could find the following method of Spring's TransactionInterceptor, which is causing this behaviour. It removes the current entitymanager from current thread when the method returns.

    Code:
    if (txAttr == null || !(getTransactionManager() instanceof CallbackPreferringPlatformTransactionManager)) {
    			// Standard transaction demarcation with getTransaction and commit/rollback calls.
    			TransactionInfo txInfo = createTransactionIfNecessary(txAttr, joinpointIdentification);
    			Object retVal = null;
    			try {
    				// This is an around advice: Invoke the next interceptor in the chain.
    				// This will normally result in a target object being invoked.
    				retVal = invocation.proceed();
    			}
    			catch (Throwable ex) {
    				// target invocation exception
    				completeTransactionAfterThrowing(txInfo, ex);
    				throw ex;
    			}
    			finally {
    				cleanupTransactionInfo(txInfo);
    			}
    			commitTransactionAfterReturning(txInfo);
    			return retVal;
    	}
    "commitTransactionAfterReturning" doesn't really commits the transaction, but it removes the entitymanager from the current thread.

    Please let me know if any one has any idea about this problem.
Working...
X