Author: jlmonteiro
Date: Wed Apr 20 16:33:29 2011
New Revision: 1095452

URL: http://svn.apache.org/viewvc?rev=1095452&view=rev
Log:
OPENEJB-1527: Fixing bad transaction management on the JtaEntityManager wrapper.
Thanks a lot Thibaut.

Added:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java
Modified:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java?rev=1095452&r1=1095451&r2=1095452&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java
 Wed Apr 20 16:33:29 2011
@@ -17,23 +17,22 @@
  */
 package org.apache.openejb.persistence;
 
-import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
 
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
 import javax.persistence.FlushModeType;
 import javax.persistence.LockModeType;
 import javax.persistence.Query;
-import javax.persistence.EntityTransaction;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
 import javax.persistence.TransactionRequiredException;
 import javax.persistence.TypedQuery;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.metamodel.Metamodel;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * The JtaEntityManager is a wrapper around an entity manager that 
automatically creates and closes entity managers
@@ -240,7 +239,10 @@ public class JtaEntityManager implements
     public boolean contains(Object entity) {
         final Timer timer = Op.contains.start(this);
         try {
-            return isTransactionActive() && 
getEntityManager().contains(entity);
+            if (!extended &&  !isTransactionActive()) {
+                return false;
+            }
+            return getEntityManager().contains(entity);
         } finally {
             timer.stop();
         }
@@ -307,6 +309,13 @@ public class JtaEntityManager implements
         }
         return query;
     }
+    
+    private <T> TypedQuery<T> proxyIfNoTx(EntityManager entityManager, 
TypedQuery<T> query) {
+        if (!extended && !isTransactionActive()) {
+            return new JtaTypedQuery<T>(entityManager, query);
+        }
+        return query;
+    }
 
     public void joinTransaction() {
         if (logger.isDebugEnabled()) {
@@ -327,70 +336,58 @@ public class JtaEntityManager implements
     public EntityTransaction getTransaction() {
         throw new IllegalStateException("A JTA EntityManager can not use the 
EntityTransaction API.  See JPA 1.0 section 5.5");
     }
-    
+
     // JPA 2.0
     /* (non-Javadoc)
      * @see javax.persistence.EntityManager#createNamedQuery(java.lang.String, 
java.lang.Class)
      */
     public <T> TypedQuery<T> createNamedQuery(String name, Class<T> 
resultClass) {
-        EntityManager entityManager = getEntityManager();
+        final Timer timer = Op.createNamedQuery.start(this);
         try {
-            final Timer timer = Op.createNamedQuery.start(this);
-            try {
-                return entityManager.createNamedQuery(name, resultClass);
-            } finally {
-                timer.stop();
-            }
+            EntityManager entityManager = getEntityManager();
+            TypedQuery<T> query = entityManager.createNamedQuery(name, 
resultClass);
+            return proxyIfNoTx(entityManager, query);
         } finally {
-            closeIfNoTx(entityManager);
+            timer.stop();
         }
     }
     /* (non-Javadoc)
      * @see 
javax.persistence.EntityManager#createQuery(javax.persistence.criteria.CriteriaQuery)
      */
     public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
-        EntityManager entityManager = getEntityManager();
+        final Timer timer = Op.createQuery.start(this);
         try {
-            final Timer timer = Op.createQuery.start(this);
-            try {
-                return entityManager.createQuery(criteriaQuery);
-            } finally {
-                timer.stop();
-            }
+            EntityManager entityManager = getEntityManager();
+            TypedQuery<T> query = entityManager.createQuery(criteriaQuery);
+            return proxyIfNoTx(entityManager, query);
         } finally {
-            closeIfNoTx(entityManager);
+            timer.stop();
         }
     }
     /* (non-Javadoc)
      * @see javax.persistence.EntityManager#createQuery(java.lang.String, 
java.lang.Class)
      */
     public <T> TypedQuery<T> createQuery(String qlString, Class<T> 
resultClass) {
-        EntityManager entityManager = getEntityManager();
+        final Timer timer = Op.createQuery.start(this);
         try {
-            final Timer timer = Op.createQuery.start(this);
-            try {
-                return entityManager.createQuery(qlString, resultClass);
-            } finally {
-                timer.stop();
-            }
+            EntityManager entityManager = getEntityManager();
+            TypedQuery<T> query = entityManager.createQuery(qlString, 
resultClass);
+            return proxyIfNoTx(entityManager, query);
         } finally {
-            closeIfNoTx(entityManager);
+            timer.stop();
         }
     }
     /* (non-Javadoc)
      * @see javax.persistence.EntityManager#detach(java.lang.Object)
      */
     public void detach(Object entity) {
-        EntityManager entityManager = getEntityManager();
+        final Timer timer = Op.detach.start(this);
         try {
-            final Timer timer = Op.detach.start(this);
-            try {
-                entityManager.detach(entity);
-            } finally {
-                timer.stop();
+            if (!extended && isTransactionActive()) {
+                getEntityManager().detach(entity);
             }
         } finally {
-            closeIfNoTx(entityManager);
+            timer.stop();
         }
     }
     /* (non-Javadoc)
@@ -451,17 +448,13 @@ public class JtaEntityManager implements
      * @see javax.persistence.EntityManager#getLockMode(java.lang.Object)
      */
     public LockModeType getLockMode(Object entity) {
-        EntityManager entityManager = getEntityManager();
+        assertTransactionActive();
+        final Timer timer = Op.getLockMode.start(this);
         try {
-            final Timer timer = Op.getLockMode.start(this);
-            try {
-                return entityManager.getLockMode(entity);
-            } finally {
-                timer.stop();
-            }
+            return getEntityManager().getLockMode(entity);
         } finally {
-            closeIfNoTx(entityManager);
-        }
+            timer.stop();
+        }        
     }
     /* (non-Javadoc)
      * @see javax.persistence.EntityManager#getMetamodel()
@@ -515,64 +508,48 @@ public class JtaEntityManager implements
      * @see javax.persistence.EntityManager#lock(java.lang.Object, 
javax.persistence.LockModeType, java.util.Map)
      */
     public void lock(Object entity, LockModeType lockMode, Map<String, Object> 
properties) {
-        EntityManager entityManager = getEntityManager();
+        assertTransactionActive();
+        final Timer timer = Op.lock.start(this);
         try {
-            final Timer timer = Op.lock.start(this);
-            try {
-                entityManager.lock(entityManager, lockMode, properties);
-            } finally {
-                timer.stop();
-            }
+            getEntityManager().lock(entity, lockMode, properties);
         } finally {
-            closeIfNoTx(entityManager);
-        }
+            timer.stop();
+        }        
     }
     /* (non-Javadoc)
      * @see javax.persistence.EntityManager#refresh(java.lang.Object, 
java.util.Map)
      */
     public void refresh(Object entity, Map<String, Object> properties) {
-        EntityManager entityManager = getEntityManager();
+        assertTransactionActive();
+        final Timer timer = Op.refresh.start(this);
         try {
-            final Timer timer = Op.refresh.start(this);
-            try {
-                entityManager.refresh(entityManager, properties);
-            } finally {
-                timer.stop();
-            }
+            getEntityManager().refresh(entity, properties);
         } finally {
-            closeIfNoTx(entityManager);
+            timer.stop();
         }
     }
     /* (non-Javadoc)
      * @see javax.persistence.EntityManager#refresh(java.lang.Object, 
javax.persistence.LockModeType)
      */
     public void refresh(Object entity, LockModeType lockMode) {
-        EntityManager entityManager = getEntityManager();
+        assertTransactionActive();
+        final Timer timer = Op.refresh.start(this);
         try {
-            final Timer timer = Op.refresh.start(this);
-            try {
-                entityManager.refresh(entityManager, lockMode);
-            } finally {
-                timer.stop();
-            }
+            getEntityManager().refresh(entity, lockMode);
         } finally {
-            closeIfNoTx(entityManager);
+            timer.stop();
         }
     }
     /* (non-Javadoc)
      * @see javax.persistence.EntityManager#refresh(java.lang.Object, 
javax.persistence.LockModeType, java.util.Map)
      */
     public void refresh(Object entity, LockModeType lockMode, Map<String, 
Object> properties) {
-        EntityManager entityManager = getEntityManager();
+        assertTransactionActive();
+        final Timer timer = Op.refresh.start(this);
         try {
-            final Timer timer = Op.refresh.start(this);
-            try {
-                entityManager.refresh(entityManager, lockMode, properties);
-            } finally {
-                timer.stop();
-            }
+            getEntityManager().refresh(entity, lockMode, properties);
         } finally {
-            closeIfNoTx(entityManager);
+            timer.stop();
         }
     }
     /* (non-Javadoc)
@@ -595,17 +572,7 @@ public class JtaEntityManager implements
      * @see javax.persistence.EntityManager#unwrap(java.lang.Class)
      */
     public <T> T unwrap(Class<T> cls) {
-        EntityManager entityManager = getEntityManager();
-        try {
-            final Timer timer = Op.unwrap.start(this);
-            try {
-                return entityManager.unwrap(cls);
-            } finally {
-                timer.stop();
-            }
-        } finally {
-            closeIfNoTx(entityManager);
-        }
+        return getEntityManager().unwrap(cls);
     }
 
     public static class Timer {

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java?rev=1095452&r1=1095451&r2=1095452&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java
 Wed Apr 20 16:33:29 2011
@@ -18,22 +18,22 @@
 package org.apache.openejb.persistence;
 
 
-import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Geronimo;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
 
-import java.util.Map;
-import java.util.HashMap;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.TransactionRequiredException;
 import javax.transaction.Status;
 import javax.transaction.Synchronization;
 import javax.transaction.TransactionSynchronizationRegistry;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
- * The JtaEntityManagerRegistry tracks JTA entity managers for transation and 
extended scoped
- * entity managers.  A signle instance of this object should be created and 
shared by all
+ * The JtaEntityManagerRegistry tracks JTA entity managers for transaction and 
extended scoped
+ * entity managers.  A single instance of this object should be created and 
shared by all
  * JtaEntityManagers in the server instance.  Failure to do this will result 
in multiple entity
  * managers being created for a single persistence until, and that will result 
in cache
  * incoherence.
@@ -48,7 +48,7 @@ public class JtaEntityManagerRegistry {
     private final TransactionSynchronizationRegistry transactionRegistry;
 
     /**
-     * Registry of entended context entity managers.
+     * Registry of extended context entity managers.
      */
     private final ThreadLocal<ExtendedRegistry> extendedRegistry = new 
ThreadLocal<ExtendedRegistry>() {
         protected ExtendedRegistry initialValue() {
@@ -65,11 +65,11 @@ public class JtaEntityManagerRegistry {
     }
 
     /**
-     * Gets an entity manager instance from the transaction registry, extended 
regitry or for a transaction scoped
-     * entity manager, creates a new one when an exisitng instance is not 
found.
+     * Gets an entity manager instance from the transaction registry, extended 
registry or for a transaction scoped
+     * entity manager, creates a new one when an existing instance is not 
found.
      * </p>
      * It is important that a component adds extended scoped entity managers 
to this registry when the component is
-     * entered and removes them when exited.  If this registration is not 
preformed, an IllegalStateException will
+     * entered and removes them when exited.  If this registration is not 
performed, an IllegalStateException will
      * be thrown when entity manger is fetched.
      * @param entityManagerFactory the entity manager factory from which an 
entity manager is required
      * @param properties the properties passed to the entity manager factory 
when an entity manager is created

Added: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java?rev=1095452&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java
 (added)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaTypedQuery.java
 Wed Apr 20 16:33:29 2011
@@ -0,0 +1,142 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.persistence;
+
+import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Parameter;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
+import javax.persistence.TypedQuery;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author Thibaut Robert
+ * 
+ * This class is the same as {@link JtaQuery} but wraps TypedQuery instead of 
Query
+ */
+public class JtaTypedQuery<X> extends JtaQuery implements TypedQuery<X> {
+
+    public JtaTypedQuery(EntityManager entityManager, Query query) {
+        super(entityManager, query);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<X> getResultList() {
+        return (List<X>) super.getResultList();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public X getSingleResult() {
+        return (X) super.getSingleResult();
+    }
+
+    @Override
+    public TypedQuery<X> setFirstResult(int i) {
+        super.setFirstResult(i);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setFlushMode(FlushModeType flushModeType) {
+        super.setFlushMode(flushModeType);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setHint(String s, Object o) {    
+        super.setHint(s, o);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setLockMode(LockModeType lockMode) {
+        super.setLockMode(lockMode);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setMaxResults(int i) {
+        super.setMaxResults(i);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(int i, Calendar calendar,
+            TemporalType temporalType) {
+        super.setParameter(i, calendar, temporalType);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(int i, Date date, TemporalType 
temporalType) {
+        super.setParameter(i, date, temporalType);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(int i, Object o) {
+        super.setParameter(i, o);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(Parameter<Calendar> param, Calendar 
value,
+            TemporalType temporalType) {
+        super.setParameter(param, value, temporalType);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(Parameter<Date> param, Date value,
+            TemporalType temporalType) {
+        super.setParameter(param, value, temporalType);
+        return this;
+    }
+
+    @Override
+    public <T> TypedQuery<X> setParameter(Parameter<T> param, T value) {
+        super.setParameter(param, value);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(String s, Calendar calendar,
+            TemporalType temporalType) {
+        super.setParameter(s, calendar, temporalType);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(String s, Date date, TemporalType 
temporalType) {
+        super.setParameter(s, date, temporalType);
+        return this;
+    }
+
+    @Override
+    public TypedQuery<X> setParameter(String s, Object o) {
+        super.setParameter(s, o);
+        return this;
+    }
+
+}


Reply via email to