title: Spring + Eclipselink + JtaTransactionManager = javax.persistence.TransactionRequiredException
body: <p>I really hope you can help me. I've been looking all over the internet for answers and none of them works.</p>
  
  <p>I use Spring 3 + JTA + EclipseLink but i'm getting a TransactionRequiredException when flushing a transaction. Now i'm very used to just defining my persistence context and injecting the EntityManager and the transaction is handled by the app server.</p>
  
  <p>So here's what I've got.</p>
  
  <p>persistence.xml</p>
  
  <pre><code>&lt;persistence version="2.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_2_0.xsd"&gt;
      &lt;persistence-unit name="CartouchanPU" transaction-type="JTA"&gt;
          &lt;provider&gt;org.eclipse.persistence.jpa.PersistenceProvider&lt;/provider&gt;
          &lt;jta-data-source&gt;java:app/jdbc/CartouchanDS&lt;/jta-data-source&gt;
          &lt;class&gt;com.cartouchan.locator.database.models.Authority&lt;/class&gt;
          &lt;class&gt;com.cartouchan.locator.database.models.AuthorityPK&lt;/class&gt;
          &lt;class&gt;com.cartouchan.locator.database.models.User&lt;/class&gt;
          &lt;class&gt;com.cartouchan.locator.database.models.UserPK&lt;/class&gt;
          &lt;exclude-unlisted-classes&gt;false&lt;/exclude-unlisted-classes&gt;
          &lt;properties&gt;
              &lt;property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/&gt;
              &lt;property name="eclipselink.ddl-generation" value="none"/&gt;
              &lt;property name="eclipselink.target-database" value="MySQL"/&gt;
              &lt;property name="eclipselink.jdbc.native-sql" value="true"/&gt;
              &lt;property name="eclipselink.jdbc.cache-statements" value="true"/&gt;
          &lt;/properties&gt;        
      &lt;/persistence-unit&gt;
  &lt;/persistence&gt;
  </code></pre>
  
  <p>spring-config.xml</p>
  
  <pre><code>&lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /&gt;
  
  &lt;jee:jndi-lookup jndi-name="java:app/jdbc/CartouchanDS" id="CartouchanDS" /&gt;
  
    &lt;bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"&gt;
      &lt;property name="autodetectUserTransaction" value="true" /&gt;
      &lt;property name="autodetectTransactionManager" value="true" /&gt;
      &lt;property name="transactionManagerName" value="java:appserver/TransactionManager"/&gt;
  &lt;/bean&gt;
  
  &lt;context:annotation-config /&gt;
  
  &lt;bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
      &lt;property name="persistenceUnitName" value="CartouchanPU" /&gt;
      &lt;property name="persistenceUnitManager"&gt;
          &lt;bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"/&gt;
      &lt;/property&gt;
      &lt;property name="loadTimeWeaver"&gt;
          &lt;bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /&gt;
      &lt;/property&gt;
      &lt;property name="jpaVendorAdapter"&gt;
          &lt;bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"&gt;
              &lt;property name="showSql" value="true" /&gt;
          &lt;/bean&gt;
      &lt;/property&gt;
      &lt;property name="jpaDialect"&gt;
          &lt;bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" /&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>CreateAccount.class</p>
  
  <pre><code>import java.text.MessageFormat;
  
  import javax.persistence.EntityManager;
  import javax.persistence.PersistenceContext;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  import org.apache.log4j.Logger;
  import org.springframework.transaction.annotation.Propagation;
  import org.springframework.transaction.annotation.Transactional;
  import org.springframework.web.bind.ServletRequestBindingException;
  import org.springframework.web.bind.ServletRequestUtils;
  import org.springframework.web.servlet.ModelAndView;
  import org.springframework.web.servlet.mvc.Controller;
  
  public class CreateAccount implements Controller {
      private static final Logger logger = Logger.getLogger(CreateAccount.class);
  
      //    @Autowired
      //    private JtaTransactionManager transactionManager;
  
      @PersistenceContext
      private EntityManager       entityManager;
  
      @Transactional(propagation = Propagation.REQUIRES_NEW)
      @Override
      public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
          logger.info(MessageFormat.format("Called handle request", ""));
          String username = ServletRequestUtils.getRequiredStringParameter(request, "username");
          logger.info(MessageFormat.format("username {0}", username));
          String password = ServletRequestUtils.getRequiredStringParameter(request, "password");
          logger.info(MessageFormat.format("password {0}", password));
          String passwordConfirm = ServletRequestUtils.getRequiredStringParameter(request, "passwordConfirm");
          logger.info(MessageFormat.format("passwordConfirm {0}", passwordConfirm));
  
          if (!password.equals(passwordConfirm)) {
              throw new ServletRequestBindingException("Passwords don't match");
          }
  
          //transactionManager.getUserTransaction().begin();
          User user = new User();
          //try {
          UserPK userPK = new UserPK();
          userPK.setUsername(username);
          user.setId(userPK);
          user.setPassword(passwordConfirm);
          user.setEnabled((byte) 1);
  
          logger.info(MessageFormat.format("persist the user {0}", username));
          entityManager.persist(user);
          entityManager.flush();
          //        logger.info(MessageFormat.format("Before Refresh user {0}", username));
          //        entityManager.refresh(user);
          //            transactionManager.getUserTransaction().commit();
          //        } catch (Exception e) {
          //            logger.error(MessageFormat.format("Got an exception {0}", e.getMessage()), e);
          //            transactionManager.getUserTransaction().rollback();
          //        }
  
          //        transactionManager.getUserTransaction().begin();
  
          //        AuthorityPK authorityPK = new AuthorityPK();
          //        //try {
          //        logger.info(MessageFormat.format("Refreshed user {0} = {1}", username, user.getId()));
          //
          //        authorityPK.setUserId(user.getId().getId());
          //        authorityPK.setAuthority(com.cartouchan.locator.models.Authority.ROLE_USER.toString());
          //        Authority authority = new Authority();
          //        authority.setId(authorityPK);
          //
          //        logger.info(MessageFormat.format("Save the authority {0}", com.cartouchan.locator.models.Authority.ROLE_USER.toString()));
          //        entityManager.persist(authority);
  
          //            transactionManager.getUserTransaction().commit();
          //        } catch (Exception e) {
          //            logger.error(MessageFormat.format("Got an exception {0}", e.getMessage()), e);
          //            transactionManager.getUserTransaction().rollback();
          //        }
  
          logger.info(MessageFormat.format("Go to /index.zul", ""));
          ModelAndView modelAndView = new ModelAndView("index");
  
          logger.info(MessageFormat.format("Return ", ""));
          return modelAndView;
      }
  }
  </code></pre>
  
  <p>So here's the deal, when I uncomment the transactionManager parts, the program operates as expected, which is I can see the insert statements. However, when using the above code, I get the following stacktrace :</p>
  
  <pre><code>INFO: Starting ZK 5.0.7.1 CE (build: 2011051910)
  INFO: Parsing jndi:/server/Cartouchan/WEB-INF/zk.xml
  INFO: WEB0671: Loading application [Cartouchan-Web] at [/Cartouchan]
  INFO: Cartouchan-Web was successfully deployed in 1,537 milliseconds.
  
  INFO: 2011-08-04 01:09:52 CreateAccount [INFO] Called handle request
  
  INFO: 2011-08-04 01:09:52 CreateAccount [INFO] username blah
  
  INFO: 2011-08-04 01:09:52 CreateAccount [INFO] password test
  
  INFO: 2011-08-04 01:09:52 CreateAccount [INFO] passwordConfirm test
  
  INFO: 2011-08-04 01:09:52 CreateAccount [INFO] persist the user blah
  
  INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
  INFO: EclipseLink, version: Eclipse Persistence Services - 2.2.0.v20110202-r8913
  CONFIG: connecting(DatabaseLogin(
      platform=&gt;MySQLPlatform
      user name=&gt; ""
      connector=&gt;JNDIConnector datasource name=&gt;null
  ))
  CONFIG: Connected: jdbc:mysql://localhost:3306/Cartouchan
      User: root@localhost
      Database: MySQL  Version: 5.1.51
      Driver: MySQL-AB JDBC Driver  Version: mysql-connector-java-5.1.11 ( Revision: ${svn.Revision} )
  CONFIG: connecting(DatabaseLogin(
      platform=&gt;MySQLPlatform
      user name=&gt; ""
      connector=&gt;JNDIConnector datasource name=&gt;null
  ))
  CONFIG: Connected: jdbc:mysql://localhost:3306/Cartouchan
      User: root@localhost
      Database: MySQL  Version: 5.1.51
      Driver: MySQL-AB JDBC Driver  Version: mysql-connector-java-5.1.11 ( Revision: ${svn.Revision} )
  INFO: file:/Applications/NetBeans/glassfish-3.1/glassfish/domains/domain1/eclipseApps/Cartouchan-Web/WEB-INF/classes/_CartouchanPU login successful
  WARNING: StandardWrapperValve[cartouchan]: PWC1406: Servlet.service() for servlet cartouchan threw exception
  javax.persistence.TransactionRequiredException: 
  Exception Description: No externally managed transaction is currently active for this thread
      at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.throwCheckTransactionFailedException(JTATransactionWrapper.java:86)
      at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.checkForTransaction(JTATransactionWrapper.java:46)
      at org.eclipse.persistence.internal.jpa.EntityManagerImpl.checkForTransaction(EntityManagerImpl.java:1666)
      at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:744)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
      at $Proxy151.flush(Unknown Source)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
      at $Proxy151.flush(Unknown Source)
      at com.cartouchan.locator.controllers.CreateAccount.handleRequest(CreateAccount.java:56)
      at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
      at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
      at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
      at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
      at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
      at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227)
      at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170)
      at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
      at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
      at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
      at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
      at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
      at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
      at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
      at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
      at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
      at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
      at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
      at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
      at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
      at java.lang.Thread.run(Thread.java:680)
  </code></pre>
  
  <p>So as you can see, it connects correctly to the database, and it "persists" the data, but never actually execute the insert statement. Then when flushing the EM, it throws the exception.</p>
  
  <p>Your help will be greatly appreciated.</p>
  
  <p>Best Regards.</p>