You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2007/04/25 00:23:05 UTC

svn commit: r532109 - in /incubator/openejb/trunk/openejb3: container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/ container/openejb-core/src/main/java/org/apache/openejb/core/cmp/ container/openejb-core/src/main/java/org/...

Author: dain
Date: Tue Apr 24 15:23:04 2007
New Revision: 532109

URL: http://svn.apache.org/viewvc?view=rev&rev=532109
Log:
Add support for CMP without an active transaction

Modified:
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml
    incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmp/CmpAllowedOperationsTests.java

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java?view=diff&rev=532109&r1=532108&r2=532109
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java Tue Apr 24 15:23:04 2007
@@ -186,6 +186,10 @@
         }
     }
 
+    public void storeBeanIfNoTx(ThreadContext callContext, Object bean) {
+        throw new UnsupportedOperationException();
+    }
+
     public void removeBean(ThreadContext callContext) {
         try {
             Database db = getDatabase();

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java?view=diff&rev=532109&r1=532108&r2=532109
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java Tue Apr 24 15:23:04 2007
@@ -64,9 +64,6 @@
 import org.apache.openejb.core.transaction.TransactionContainer;
 import org.apache.openejb.core.transaction.TransactionContext;
 import org.apache.openejb.core.transaction.TransactionPolicy;
-import org.apache.openejb.core.transaction.TxManditory;
-import org.apache.openejb.core.transaction.TxRequired;
-import org.apache.openejb.core.transaction.TxRequiresNew;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Enumerator;
 
@@ -327,15 +324,6 @@
         }
     }
 
-    private TransactionPolicy getTransactionPolicy(CoreDeploymentInfo deploymentInfo, Method callMethod) {
-        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
-        // for CMP1 convert non-transactional policies to Required
-        if (!deploymentInfo.isCmp2() && !(txPolicy instanceof TxRequired) && !(txPolicy instanceof TxRequiresNew) && !(txPolicy instanceof TxManditory)) {
-            txPolicy = new TxRequired(this);
-        }
-        return txPolicy;
-    }
-
     private ThreadContext createThreadContext(EntityBean entityBean) {
         if (entityBean == null) throw new NullPointerException("entityBean is null");
 
@@ -515,7 +503,7 @@
 
     private Object businessMethod(Method callMethod, Method runMethod, Object[] args, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        TransactionPolicy txPolicy = getTransactionPolicy(deploymentInfo, callMethod);
+        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
         TransactionContext txContext = new TransactionContext(callContext, transactionManager);
 
         txPolicy.beforeInvoke(null, txContext);
@@ -533,6 +521,8 @@
 
             returnValue = runMethod.invoke(bean, args);
 
+            // when there is not transaction, merge the data from the bean back into the cmp engine
+            cmpEngine.storeBeanIfNoTx(callContext, bean);
         } catch (InvocationTargetException ite) {
             ExceptionType type = callContext.getDeploymentInfo().getExceptionType(ite.getTargetException());
             if (type == ExceptionType.SYSTEM) {
@@ -558,7 +548,7 @@
 
     private Object homeMethod(Method callMethod, Object[] args, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        TransactionPolicy txPolicy = getTransactionPolicy(deploymentInfo, callMethod);
+        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
         TransactionContext txContext = new TransactionContext(callContext, transactionManager);
 
         txPolicy.beforeInvoke(null, txContext);
@@ -613,10 +603,7 @@
         EntityBean bean = null;
         Object primaryKey = null;
 
-        TransactionPolicy txPolicy = getTransactionPolicy(deploymentInfo, callMethod);
-        if (!(txPolicy instanceof TxRequired) && !(txPolicy instanceof TxRequiresNew) && !(txPolicy instanceof TxManditory)) {
-            throw new IllegalArgumentException("Only required, requires new, and manditory transaction policies are supported for CMP beans: " + txPolicy.getClass().getName());
-        }
+        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
         TransactionContext txContext = new TransactionContext(callContext, transactionManager);
 
         txPolicy.beforeInvoke(bean, txContext);
@@ -665,6 +652,8 @@
                 ThreadContext.exit(oldContext);
             }
 
+            // when there is not transaction, merge the data from the bean back into the cmp engine
+            cmpEngine.storeBeanIfNoTx(callContext, bean);
         } catch (InvocationTargetException ite) {// handle enterprise bean exceptions
             ExceptionType type = callContext.getDeploymentInfo().getExceptionType(ite.getTargetException());
             if (type == ExceptionType.SYSTEM) {
@@ -689,7 +678,7 @@
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
 
         // Get the transaction policy assigned to this method
-        TransactionPolicy txPolicy = getTransactionPolicy(deploymentInfo, callMethod);
+        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
         TransactionContext txContext = new TransactionContext(callContext, transactionManager);
 
         txPolicy.beforeInvoke(null, txContext);
@@ -720,7 +709,7 @@
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
 
         // Get the transaction policy assigned to this method
-        TransactionPolicy txPolicy = getTransactionPolicy(deploymentInfo, callMethod);
+        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
         TransactionContext txContext = new TransactionContext(callContext, transactionManager);
 
         txPolicy.beforeInvoke(null, txContext);
@@ -851,7 +840,7 @@
     private void removeEJBObject(Method callMethod, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
         TransactionContext txContext = new TransactionContext(callContext, transactionManager);
-        TransactionPolicy txPolicy = getTransactionPolicy(deploymentInfo, callMethod);
+        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
 
         txPolicy.beforeInvoke(null, txContext);
         try {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java?view=diff&rev=532109&r1=532108&r2=532109
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java Tue Apr 24 15:23:04 2007
@@ -26,6 +26,7 @@
 import javax.ejb.EntityBean;
 import javax.ejb.CreateException;
 import javax.ejb.FinderException;
+import javax.transaction.TransactionManager;
 import java.util.List;
 import java.lang.reflect.Method;
 
@@ -34,6 +35,8 @@
     Object createBean(EntityBean entity, ThreadContext callContext) throws CreateException;
 
     Object loadBean(ThreadContext callContext, Object primaryKey);
+
+    void storeBeanIfNoTx(ThreadContext callContext, Object bean);
 
     void removeBean(ThreadContext callContext);
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java?view=diff&rev=532109&r1=532108&r2=532109
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java Tue Apr 24 15:23:04 2007
@@ -35,6 +35,8 @@
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceException;
 import javax.persistence.Query;
+import javax.transaction.TransactionManager;
+import javax.transaction.Status;
 
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.core.CoreDeploymentInfo;
@@ -55,6 +57,7 @@
     public static final String CMP_PERSISTENCE_CONTEXT_REF_NAME = "openejb/cmp";
 
     private final CmpCallback cmpCallback;
+    private final TransactionManager transactionManager;
     private final WeakHashMap<EntityManager,Object> entityManagerListeners = new WeakHashMap<EntityManager,Object>();
 
     private final Map<Object, CoreDeploymentInfo> deployments = new HashMap<Object, CoreDeploymentInfo>();
@@ -64,8 +67,9 @@
         }
     };
 
-    public JpaCmpEngine(CmpCallback cmpCallback) {
+    public JpaCmpEngine(CmpCallback cmpCallback, TransactionManager transactionManager) {
         this.cmpCallback = cmpCallback;
+        this.transactionManager = transactionManager;
     }
 
     public void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
@@ -129,6 +133,7 @@
         EntityManager entityManager = getEntityManager(deploymentInfo);
 
         // TODO verify that extract primary key requires a flush followed by a merge
+        boolean startedTx = startTransaction("persist");
         creating.get().add(bean);
         try {
             entityManager.persist(bean);
@@ -136,6 +141,7 @@
             bean = entityManager.merge(bean);
         } finally {
             creating.get().remove(bean);
+            commitTransaction(startedTx, "persist");
         }
 
         // extract the primary key from the bean
@@ -146,20 +152,44 @@
     }
 
     public Object loadBean(ThreadContext callContext, Object primaryKey) {
-        CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        Class<?> beanClass = deploymentInfo.getCmpImplClass();
-        EntityManager entityManager = getEntityManager(deploymentInfo);
-        Object bean = entityManager.find(beanClass, primaryKey);
-        return bean;
+        boolean startedTx = startTransaction("load");
+        try {
+            CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
+            Class<?> beanClass = deploymentInfo.getCmpImplClass();
+            EntityManager entityManager = getEntityManager(deploymentInfo);
+            Object bean = entityManager.find(beanClass, primaryKey);
+            return bean;
+        } finally {
+            commitTransaction(startedTx, "load");
+        }
+    }
+
+    public void storeBeanIfNoTx(ThreadContext callContext, Object bean) {
+        boolean startedTx = startTransaction("store");
+        if (startedTx) {
+            CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
+
+            try {
+                EntityManager entityManager = getEntityManager(deploymentInfo);
+                entityManager.merge(bean);
+            } finally {
+                commitTransaction(startedTx, "store");
+            }
+        }
     }
 
     public void removeBean(ThreadContext callContext) {
-        CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        Class<?> beanClass = deploymentInfo.getCmpImplClass();
+        boolean startedTx = startTransaction("remove");
+        try {
+            CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
+            Class<?> beanClass = deploymentInfo.getCmpImplClass();
 
-        EntityManager entityManager = getEntityManager(deploymentInfo);
-        Object bean = entityManager.find(beanClass, callContext.getPrimaryKey());
-        entityManager.remove(bean);
+            EntityManager entityManager = getEntityManager(deploymentInfo);
+            Object bean = entityManager.find(beanClass, callContext.getPrimaryKey());
+            entityManager.remove(bean);
+        } finally {
+            commitTransaction(startedTx, "remove");
+        }
     }
 
     public List<Object> queryBeans(ThreadContext callContext, Method queryMethod, Object[] args) throws FinderException {
@@ -180,32 +210,43 @@
             queryName.append(')');
 
         }
-        String fullName = queryName.toString();
-        Query query = createNamedQuery(entityManager, fullName);
-        if (query == null) {
-            query = createNamedQuery(entityManager, shortName);
+
+        boolean startedTx = startTransaction("query");
+        try {
+            String fullName = queryName.toString();
+            Query query = createNamedQuery(entityManager, fullName);
             if (query == null) {
-                throw new FinderException("No query defined for method " + fullName);
+                query = createNamedQuery(entityManager, shortName);
+                if (query == null) {
+                    throw new FinderException("No query defined for method " + fullName);
+                }
             }
+            return executeQuery(query, args);
+        } finally {
+            commitTransaction(startedTx, "query");
         }
-        return executeQuery(query, args);
     }
 
     public List<Object> queryBeans(CoreDeploymentInfo deploymentInfo, String signature, Object[] args) throws FinderException {
         EntityManager entityManager = getEntityManager(deploymentInfo);
 
-        Query query = createNamedQuery(entityManager, signature);
-        if (query == null) {
-            int parenIndex = signature.indexOf('(');
-            if (parenIndex > 0) {
-                String shortName = signature.substring(0, parenIndex);
-                query = createNamedQuery(entityManager, shortName);
-            }
+        boolean startedTx = startTransaction("query");
+        try {
+            Query query = createNamedQuery(entityManager, signature);
             if (query == null) {
-                throw new FinderException("No query defined for method " + signature);
+                int parenIndex = signature.indexOf('(');
+                if (parenIndex > 0) {
+                    String shortName = signature.substring(0, parenIndex);
+                    query = createNamedQuery(entityManager, shortName);
+                }
+                if (query == null) {
+                    throw new FinderException("No query defined for method " + signature);
+                }
             }
+            return executeQuery(query, args);
+        } finally {
+            commitTransaction(startedTx, "query");
         }
-        return executeQuery(query, args);
     }
 
     private List<Object> executeQuery(Query query, Object[] args) {
@@ -232,6 +273,7 @@
             if (value instanceof EntityBean) {
                 // todo don't activate beans already activated
                 EntityBean entity = (EntityBean) value;
+                cmpCallback.setEntityContext(entity);
                 cmpCallback.ejbActivate(entity);
             }
         }
@@ -246,6 +288,29 @@
             // soooo lame that jpa throws an exception instead of returning null....
             ignored.printStackTrace();
             return null;
+        }
+    }
+
+    private boolean startTransaction(String operation) {
+        try {
+            if (Status.STATUS_NO_TRANSACTION == transactionManager.getStatus()) {
+                transactionManager.begin();
+                return true;
+            }
+            return false;
+        } catch (Exception e) {
+            throw new EJBException("Unable to start transaction for " + operation + " operation", e);
+        }
+    }
+
+    private void commitTransaction(boolean startedTx, String operation) {
+        try {
+            if (startedTx) {
+                transactionManager.commit();
+            }
+        } catch (Exception e) {
+            //noinspection ThrowFromFinallyBlock
+            throw new EJBException("Unable to complete transaction for " + operation + " operation");
         }
     }
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java?view=diff&rev=532109&r1=532108&r2=532109
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java Tue Apr 24 15:23:04 2007
@@ -81,6 +81,6 @@
     }
 
     public CmpEngine create() throws OpenEJBException {
-        return new JpaCmpEngine(cmpCallback);
+        return new JpaCmpEngine(cmpCallback, transactionManager);
     }
 }

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml?view=diff&rev=532109&r1=532108&r2=532109
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml Tue Apr 24 15:23:04 2007
@@ -5586,28 +5586,28 @@
         <ejb-name>BasicCmpBean</ejb-name>
         <method-name>*</method-name>
       </method>
-      <trans-attribute>Required</trans-attribute>
+      <trans-attribute>Supports</trans-attribute>
     </container-transaction>
     <container-transaction>
       <method>
         <ejb-name>AOBasicCmpBean</ejb-name>
         <method-name>*</method-name>
       </method>
-      <trans-attribute>Required</trans-attribute>
+      <trans-attribute>Supports</trans-attribute>
     </container-transaction>
     <container-transaction>
       <method>
         <ejb-name>EncCmpBean</ejb-name>
         <method-name>*</method-name>
       </method>
-      <trans-attribute>Required</trans-attribute>
+      <trans-attribute>Supports</trans-attribute>
     </container-transaction>
     <container-transaction>
       <method>
         <ejb-name>Cmp RMI-IIOP Bean</ejb-name>
         <method-name>*</method-name>
       </method>
-      <trans-attribute>Required</trans-attribute>
+      <trans-attribute>Supports</trans-attribute>
     </container-transaction>
 
     <!-- CMR Test Beans -->

Modified: incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmp/CmpAllowedOperationsTests.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmp/CmpAllowedOperationsTests.java?view=diff&rev=532109&r1=532108&r2=532109
==============================================================================
--- incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmp/CmpAllowedOperationsTests.java (original)
+++ incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/entity/cmp/CmpAllowedOperationsTests.java Tue Apr 24 15:23:04 2007
@@ -266,7 +266,7 @@
         OperationsPolicy policy = new OperationsPolicy();
         policy.allow( OperationsPolicy.Context_getEJBHome );
         policy.allow( OperationsPolicy.Context_getCallerPrincipal );
-        policy.allow( OperationsPolicy.Context_getRollbackOnly );
+//        policy.allow( OperationsPolicy.Context_getRollbackOnly );
         policy.allow( OperationsPolicy.Context_isCallerInRole );
 //        policy.allow( OperationsPolicy.Context_setRollbackOnly );
         policy.allow( OperationsPolicy.JNDI_access_to_java_comp_env );
@@ -306,7 +306,7 @@
         OperationsPolicy policy = new OperationsPolicy();
         policy.allow( OperationsPolicy.Context_getEJBHome );
         policy.allow( OperationsPolicy.Context_getCallerPrincipal );
-        policy.allow( OperationsPolicy.Context_getRollbackOnly );
+//        policy.allow( OperationsPolicy.Context_getRollbackOnly );
         policy.allow( OperationsPolicy.Context_isCallerInRole );
 //        policy.allow( OperationsPolicy.Context_setRollbackOnly );
         policy.allow( OperationsPolicy.Context_getEJBObject );
@@ -427,7 +427,7 @@
         OperationsPolicy policy = new OperationsPolicy();
         policy.allow( OperationsPolicy.Context_getEJBHome );
         policy.allow( OperationsPolicy.Context_getCallerPrincipal );
-        policy.allow( OperationsPolicy.Context_getRollbackOnly );
+//        policy.allow( OperationsPolicy.Context_getRollbackOnly );
         policy.allow( OperationsPolicy.Context_isCallerInRole );
 //        policy.allow( OperationsPolicy.Context_setRollbackOnly );
         policy.allow( OperationsPolicy.JNDI_access_to_java_comp_env );
@@ -657,7 +657,7 @@
         OperationsPolicy policy = new OperationsPolicy();
         policy.allow( OperationsPolicy.Context_getEJBHome );
         policy.allow( OperationsPolicy.Context_getCallerPrincipal );
-        policy.allow( OperationsPolicy.Context_getRollbackOnly );
+//        policy.allow( OperationsPolicy.Context_getRollbackOnly );
         policy.allow( OperationsPolicy.Context_isCallerInRole );
 //        policy.allow( OperationsPolicy.Context_setRollbackOnly );
         policy.allow( OperationsPolicy.Context_getEJBObject );