[ https://issues.apache.org/jira/browse/OLINGO-976?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15407609#comment-15407609 ]
Enrique Rodriguez commented on OLINGO-976: ------------------------------------------ Hi Michael, Alex, I agree with Alex, and i'm working with olingo using JTA with Bean Managed Transaction on a javaee 6 application server (Websphere 8.5) First of all, I use CDI to inject dependecies (EntityManager, EntityManagerFactory ans UserTransaction). To do it we need to give the control to the container from the servlet, so I extend ODataServlet to inject the ODataJPAServiceFactory overriding getServiceFactory method @WebServlet("/OData.svc/*") public class JtaODataServlet extends ODataServlet{ public JtaODataServlet() { super(); } /** * */ private static final long serialVersionUID = 7405803151288216396L; @javax.inject.Inject private JpaInjectedServiceFactory serviceFactory; /** * Get the service factory instance which is used for creation of the * <code>ODataService</code> which handles the processing of the request. * * * @param request the http request which is processed as an OData request * @return an instance of an ODataServiceFactory */ protected ODataServiceFactory getServiceFactory(HttpServletRequest request) { return (ODataJPAServiceFactory)serviceFactory; } } The JpaInjectedServiceFactory load all resources it need from container. In also need to modify oDataJpaContext and oDataJpaContextImpl to store userTransaction and TransactionSynchronizationRegistry public class JpaInjectedServiceFactory extends ODataJPAServiceFactory { public static final String DEFAULT_ENTITY_UNIT_NAME = "Model"; @PersistenceContext//(unitName = "Model") private EntityManager entityManager; @PersistenceUnit private EntityManagerFactory emf; @Resource UserTransaction userTran; @Resource TransactionSynchronizationRegistry tsr; public JpaInjectedServiceFactory() {} @Override public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException { ODataJPAContext oDataJPAContext = getODataJPAContext(); //Context ctx; try { // ctx = new InitialContext(); // Now get the EntityManager from JNDI oDataJPAContext.setEntityManagerFactory(emf); oDataJPAContext.setEntityManager(entityManager); oDataJPAContext.setPersistenceUnitName(DEFAULT_ENTITY_UNIT_NAME); oDataJPAContext.setContainerManaged(true); oDataJPAContext.setUserTransaction(userTran, tsr); return oDataJPAContext; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } OdataJPAContextImpl now manage to create the transaction it needs, ( i think that using callback for this configuration is very complex for most of people.) @Override public ODataJPATransaction getODataJPATransaction() { if (transaction == null) { transaction = odataContext.getServiceFactory().getCallback(ODataJPATransaction.class); if (transaction == null) { if (containerManaged){ transaction = new ODataJPATransactionBeanManaged(userTran, tsr); }else{ transaction = new ODataJPATransactionLocalDefault(getEntityManager()); } } } return transaction; } Finallly ODataJPATransactionBeanManaged control the JTA transaction similar as Local transaction. public class ODataJPATransactionBeanManaged implements ODataJPATransaction { private UserTransaction userTran; private TransactionSynchronizationRegistry tsr; public ODataJPATransactionBeanManaged(UserTransaction userTran,TransactionSynchronizationRegistry tsr) { this.userTran = userTran; this.tsr = tsr; } @Override public void begin() { try { userTran.begin(); } catch (Exception e) { throw new RuntimeException("error begin transaction", e); } } @Override public void commit() { try { userTran.commit(); } catch (Exception e) { throw new RuntimeException("error begin transaction", e); } } @Override public void rollback() { try{ userTran.rollback(); } catch (Exception e) { throw new RuntimeException("error rollback transaction", e); } /** do nothing for CMP */ } @Override public boolean isActive() { if (tsr.getTransactionStatus()==Status.STATUS_ACTIVE ){ return true; }else { return false; } } } I made more changes to code to make olingo run with websphere 8.5 using Apache OpenJPA.... but this is for other post. I hope this comments help, i spend a lot of time making it work. Enrique. > Problem with JTA transactions > ----------------------------- > > Key: OLINGO-976 > URL: https://issues.apache.org/jira/browse/OLINGO-976 > Project: Olingo > Issue Type: Bug > Components: odata2-jpa > Affects Versions: V2 2.0.7 > Environment: neo-javaee6-wp-sdk (SAP HANA cloud) > Reporter: Alex Key > Assignee: Michael Bolz > Fix For: V2 2.0.7 > > > There are still problems with JTA transaction after fixing OLINGO-882. > At the moment IllegalStateException is thrown by > ODataJPATransactionLocalDefault constructor, which has em.getTransaction() > call. > Here's stacktrace: > {code} > java.lang.IllegalStateException: A JTA EntityManager can not use the > EntityTransaction API. See JPA 1.0 section 5.5 > at > org.apache.openejb.persistence.JtaEntityManager.getTransaction(JtaEntityManager.java:349) > at > org.apache.olingo.odata2.jpa.processor.core.ODataJPATransactionLocalDefault.<init>(ODataJPATransactionLocalDefault.java:31) > at > org.apache.olingo.odata2.jpa.processor.core.ODataJPAContextImpl.getODataJPATransaction(ODataJPAContextImpl.java:178) > at > org.apache.olingo.odata2.jpa.processor.core.access.data.JPAProcessorImpl.setTransaction(JPAProcessorImpl.java:451) > at > org.apache.olingo.odata2.jpa.processor.core.access.data.JPAProcessorImpl.processCreate(JPAProcessorImpl.java:335) > at > org.apache.olingo.odata2.jpa.processor.core.access.data.JPAProcessorImpl.process(JPAProcessorImpl.java:223) > at > org.apache.olingo.odata2.jpa.processor.core.ODataJPAProcessorDefault.createEntity(ODataJPAProcessorDefault.java:122) > at org.apache.olingo.odata2.core.Dispatcher.dispatch(Dispatcher.java:79) > at > org.apache.olingo.odata2.core.ODataRequestHandler.handle(ODataRequestHandler.java:130) > at > org.apache.olingo.odata2.core.rest.ODataSubLocator.handle(ODataSubLocator.java:164) > at > org.apache.olingo.odata2.core.rest.ODataSubLocator.handlePost(ODataSubLocator.java:86) > {code} -- This message was sent by Atlassian JIRA (v6.3.4#6332)