You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ma...@apache.org on 2010/02/03 18:54:19 UTC

svn commit: r906152 - in /incubator/aries/trunk/jpa/jpa-container-context/src: main/java/org/apache/aries/jpa/container/context/impl/ main/java/org/apache/aries/jpa/container/context/namespace/ main/java/org/apache/aries/jpa/container/context/transacti...

Author: mahrwald
Date: Wed Feb  3 17:54:18 2010
New Revision: 906152

URL: http://svn.apache.org/viewvc?rev=906152&view=rev
Log:
ARIES-131 Improve JTAEntityManager behaviour when there is no active transaction

Added:
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextFactory.java
      - copied, changed from r904034, incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextServiceFactory.java
Removed:
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextServiceFactory.java
Modified:
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java
    incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManagerTest.java
    incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java

Copied: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextFactory.java (from r904034, incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextServiceFactory.java)
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextFactory.java?p2=incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextFactory.java&p1=incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextServiceFactory.java&r1=904034&r2=906152&rev=906152&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextServiceFactory.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/ManagedPersistenceContextFactory.java Wed Feb  3 17:54:18 2010
@@ -20,28 +20,27 @@
 
 import java.util.Map;
 
+import javax.persistence.Cache;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.PersistenceContextType;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.metamodel.Metamodel;
 
 import org.apache.aries.jpa.container.context.transaction.impl.JTAEntityManager;
 import org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
 /**
  * A service factory that can lazily create persistence contexts
  */
-public class ManagedPersistenceContextServiceFactory implements ServiceFactory {
+public class ManagedPersistenceContextFactory implements EntityManagerFactory {
 
   private final ServiceReference emf;
   private final Map<String, Object> properties;
   private final JTAPersistenceContextRegistry registry;
-  
-  private EntityManager em;
-  
-  public ManagedPersistenceContextServiceFactory(ServiceReference unit,
+    
+  public ManagedPersistenceContextFactory(ServiceReference unit,
       Map<String, Object> props, JTAPersistenceContextRegistry contextRegistry) {
 
       emf = unit;
@@ -50,29 +49,49 @@
       
   }
 
-  public Object getService(Bundle bundle, ServiceRegistration registration) {
+  public EntityManager createEntityManager() {
+    EntityManagerFactory factory = (EntityManagerFactory) emf.getBundle().getBundleContext().getService(emf);
     
-    if(em == null) {
-      EntityManagerFactory factory = (EntityManagerFactory) emf.getBundle().getBundleContext().getService(emf);
-      
-      synchronized(this) {
-        if (em == null) {
-          PersistenceContextType type = (PersistenceContextType) properties.get(PersistenceContextManager.PERSISTENCE_CONTEXT_TYPE);
-          if(type == PersistenceContextType.TRANSACTION || type == null)
-            em = new JTAEntityManager(factory, properties, registry);
-          else {
-            //TODO add support, or log the failure
-          }
-        }
-      }
+    PersistenceContextType type = (PersistenceContextType) properties.get(PersistenceContextManager.PERSISTENCE_CONTEXT_TYPE);
+    if(type == PersistenceContextType.TRANSACTION || type == null)
+      return new JTAEntityManager(factory, properties, registry);
+    else {
+      //TODO add support, or log the failure
+      return null;
     }
-    return em;
+
+  }
+
+  public void close() {
+    throw new UnsupportedOperationException();
+  }
+  
+  public EntityManager createEntityManager(Map arg0) {
+    throw new UnsupportedOperationException();
   }
 
-  public void ungetService(Bundle bundle, ServiceRegistration registration,
-      Object service) {
-    //No-op
+  public Cache getCache() {
+    throw new UnsupportedOperationException();
+  }
+
+  public CriteriaBuilder getCriteriaBuilder() {
+    throw new UnsupportedOperationException();
+  }
+
+  public Metamodel getMetamodel() {
+    throw new UnsupportedOperationException();
+  }
+
+  public PersistenceUnitUtil getPersistenceUnitUtil() {
+    throw new UnsupportedOperationException();
+  }
+
+  public Map<String, Object> getProperties() {
+    throw new UnsupportedOperationException();
+  }
 
+  public boolean isOpen() {
+    throw new UnsupportedOperationException();
   }
 
 }

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java?rev=906152&r1=906151&r2=906152&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManager.java Wed Feb  3 17:54:18 2010
@@ -24,10 +24,11 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
 import javax.persistence.PersistenceContextType;
 
 import org.apache.aries.jpa.container.PersistenceUnitConstants;
+import org.apache.aries.jpa.container.context.namespace.NSHandler;
 import org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -35,7 +36,6 @@
 import org.osgi.framework.Filter;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.util.tracker.ServiceTracker;
@@ -194,14 +194,14 @@
   }
 
   /**
-   * Register a {@link ManagedPersistenceContextServiceFactory} for the named persistence context
+   * Register a {@link ManagedPersistenceContextFactory} for the named persistence context
    * 
    * This must <b>never</b> be called from a <code>synchronized</code> block.
    * @param name
    */
   private void registerEM(String name) {
     
-    ServiceFactory entityManagerServiceFactory;
+    EntityManagerFactory entityManagerServiceFactory;
     ServiceReference unit;
     ServiceRegistration reg = null;
     boolean alreadyRegistered = false;
@@ -226,7 +226,7 @@
           return;
 
         //Create the service factory
-        entityManagerServiceFactory = new ManagedPersistenceContextServiceFactory(unit, props, persistenceContextRegistry);
+        entityManagerServiceFactory = new ManagedPersistenceContextFactory(unit, props, persistenceContextRegistry);
       }
      
       //Always register from outside a synchronized 
@@ -237,10 +237,11 @@
       props.put(PersistenceUnitConstants.CONTAINER_MANAGED_PERSISTENCE_UNIT, Boolean.TRUE);
       props.put(PersistenceUnitConstants.OSGI_UNIT_PROVIDER, unit.getProperty(PersistenceUnitConstants.OSGI_UNIT_PROVIDER));
       props.put(PersistenceUnitConstants.EMPTY_PERSISTENCE_UNIT_NAME, "".equals(name));
+      props.put(NSHandler.PROXY_FACTORY_EMF_ATTRIBUTE, "true");
       
       BundleContext persistenceBundleContext = unit.getBundle().getBundleContext();
       reg = persistenceBundleContext.registerService(
-          EntityManager.class.getName(), entityManagerServiceFactory, props);
+          EntityManagerFactory.class.getName(), entityManagerServiceFactory, props);
     } finally {
       //As we have to register from outside a synchronized then someone may be trying to
       //unregister us. They will try to wait for us to finish, but in order to prevent 

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java?rev=906152&r1=906151&r2=906152&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/namespace/NSHandler.java Wed Feb  3 17:54:18 2010
@@ -26,13 +26,14 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.PersistenceContextType;
 
 import org.apache.aries.blueprint.NamespaceHandler;
 import org.apache.aries.blueprint.ParserContext;
 import org.apache.aries.blueprint.PassThroughMetadata;
+import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
+import org.apache.aries.blueprint.mutable.MutableRefMetadata;
 import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
 import org.apache.aries.jpa.container.PersistenceUnitConstants;
 import org.apache.aries.jpa.container.context.PersistenceManager;
@@ -44,6 +45,7 @@
 import org.osgi.service.blueprint.reflect.MapEntry;
 import org.osgi.service.blueprint.reflect.MapMetadata;
 import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
 import org.osgi.service.blueprint.reflect.Target;
 import org.osgi.service.blueprint.reflect.ValueMetadata;
@@ -69,6 +71,8 @@
   
   public static final String EMPTY_UNIT_NAME_FILTER = 
     "(" + PersistenceUnitConstants.EMPTY_PERSISTENCE_UNIT_NAME + "=true)";
+  
+  public static final String PROXY_FACTORY_EMF_ATTRIBUTE = "org.apache.aries.jpa.proxy.factory";
 
   private static final String ACTIVATION_EAGER = "EAGER";
   
@@ -96,7 +100,7 @@
       throw new IllegalArgumentException();
     
     final BeanProperty beanProperty = createInjectMetadata(element, 
-        TAG_UNIT.equals(element.getLocalName()) ? EntityManagerFactory.class : EntityManager.class,
+        TAG_UNIT.equals(element.getLocalName()),
         context);
       
     if (TAG_CONTEXT.equals(element.getLocalName())) {
@@ -176,7 +180,7 @@
     throw new UnsupportedOperationException();
   }
   
-  private BeanProperty createInjectMetadata(Element element, Class<?> clazz, ParserContext ctx) {
+  private BeanProperty createInjectMetadata(Element element, boolean isPersistenceUnit, ParserContext ctx) {
     String unitName = parseUnitName(element);
     final String property = parseProperty(element);
 
@@ -184,20 +188,32 @@
     refMetadata.setActivation(ACTIVATION_EAGER.equalsIgnoreCase(ctx.getDefaultActivation()) ?
         ReferenceMetadata.ACTIVATION_EAGER : ReferenceMetadata.ACTIVATION_LAZY);
     refMetadata.setAvailability(ReferenceMetadata.AVAILABILITY_MANDATORY);
-    refMetadata.setInterface(clazz.getName());    
+    refMetadata.setInterface(EntityManagerFactory.class.getName());    
     
+    StringBuilder filter = new StringBuilder("(&");
+    if (isPersistenceUnit)
+      filter.append("(!(").append(PROXY_FACTORY_EMF_ATTRIBUTE).append("=*))");
+    else
+      filter.append("(").append(PROXY_FACTORY_EMF_ATTRIBUTE).append("=*)");      
+      
     if (!"".equals(unitName))
-      refMetadata.setFilter("(" + PersistenceUnitConstants.OSGI_UNIT_NAME + "=" + unitName + ")");
+      filter.append("(" + PersistenceUnitConstants.OSGI_UNIT_NAME + "=" + unitName + ")");
     else
-      refMetadata.setFilter(EMPTY_UNIT_NAME_FILTER);
+      filter.append(EMPTY_UNIT_NAME_FILTER);
     
+    filter.append(")");
+    
+    refMetadata.setFilter(filter.toString());
     refMetadata.setTimeout(Integer.parseInt(ctx.getDefaultTimeout()));
     refMetadata.setDependsOn((List<String>) Collections.EMPTY_LIST);
     refMetadata.setId(ctx.generateId());
-        
+            
+    final Metadata target = isPersistenceUnit ? refMetadata 
+        : createInjectionBeanMetedata(ctx, refMetadata);
+    
     return new BeanProperty() {      
       public Metadata getValue() {
-        return refMetadata;
+        return target;
       }
       
       public String getName() {
@@ -206,6 +222,20 @@
     };
   }
   
+  private Metadata createInjectionBeanMetedata(ParserContext ctx, ReferenceMetadata factory) {
+    ctx.getComponentDefinitionRegistry().registerComponentDefinition(factory);
+    
+    MutableBeanMetadata meta = (MutableBeanMetadata) ctx.createMetadata(BeanMetadata.class);
+    MutableRefMetadata ref = (MutableRefMetadata) ctx.createMetadata(RefMetadata.class);
+    ref.setComponentId(factory.getId());
+    meta.setFactoryComponent(ref);
+    meta.setActivation(factory.getActivation());
+    meta.setFactoryMethod("createEntityManager");
+    meta.setScope(BeanMetadata.SCOPE_PROTOTYPE);
+    
+    return meta;
+  }
+  
   private Bundle getBlueprintBundle(ParserContext context) {
     PassThroughMetadata metadata = (PassThroughMetadata) context.getComponentDefinitionRegistry()
       .getComponentDefinition("blueprintBundle");

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java?rev=906152&r1=906151&r2=906152&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java Wed Feb  3 17:54:18 2010
@@ -26,6 +26,7 @@
 import javax.persistence.FlushModeType;
 import javax.persistence.LockModeType;
 import javax.persistence.Query;
+import javax.persistence.TransactionRequiredException;
 import javax.persistence.TypedQuery;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
@@ -39,6 +40,7 @@
   private final EntityManagerFactory emf;
   private final Map<String, Object> props;
   private final JTAPersistenceContextRegistry reg;
+  private EntityManager detachedManager = null;
   
   public JTAEntityManager(EntityManagerFactory factory,
       Map<String, Object> properties, JTAPersistenceContextRegistry registry) {
@@ -47,11 +49,42 @@
     reg = registry;
   }
 
+  /**
+   * Get the target persistence context
+   * @param forceTransaction Whether the returned entity manager needs to be bound to a transaction
+   * @throws TransactionRequiredException if forceTransaction is true and no transaction is available
+   * @return
+   */
+  private EntityManager getPersistenceContext(boolean forceTransaction) 
+  {
+    if (forceTransaction) {
+      return reg.getCurrentPersistenceContext(emf, props);
+    } else {
+      if (reg.isTransactionActive()) {
+        return reg.getCurrentPersistenceContext(emf, props);
+      } else {
+        if (detachedManager == null) {
+          EntityManager temp = emf.createEntityManager(props);
+          
+          synchronized (this) {
+            if (detachedManager == null) {
+              detachedManager = temp;
+              temp = null;
+            }
+          }
+          
+          if (temp != null)
+            temp.close();
+        }
+        
+        return detachedManager;
+      }
+    }
+  }
+  
   public void clear()
   {
-    EntityManager em = reg.getCurrentOrNoPersistenceContext(emf, props);
-    if(em != null)
-      em.clear();
+    getPersistenceContext(false).clear();
   }
 
   public void close()
@@ -62,62 +95,61 @@
 
   public boolean contains(Object arg0)
   {
-    EntityManager em = reg.getCurrentOrNoPersistenceContext(emf, props);
-    if(em != null)
-     return em.contains(arg0);
-    else
-      return false;
+    return getPersistenceContext(false).contains(arg0);
   }
 
   public Query createNamedQuery(String arg0)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createNamedQuery(arg0);
+    return getPersistenceContext(false).createNamedQuery(arg0);
   }
 
   public Query createNativeQuery(String arg0)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createNativeQuery(arg0);
+    return getPersistenceContext(false).createNativeQuery(arg0);
   }
 
   @SuppressWarnings("unchecked")
   public Query createNativeQuery(String arg0, Class arg1)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createNativeQuery(arg0, arg1);
+    return getPersistenceContext(false).createNativeQuery(arg0, arg1);
   }
 
   public Query createNativeQuery(String arg0, String arg1)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createNativeQuery(arg0, arg1);
+    return getPersistenceContext(false).createNativeQuery(arg0, arg1);
   }
 
   public Query createQuery(String arg0)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createQuery(arg0);
+    return getPersistenceContext(false).createQuery(arg0);
   }
 
   public <T> T find(Class<T> arg0, Object arg1)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).find(arg0, arg1);
+    return getPersistenceContext(false).find(arg0, arg1);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void flush()
   {
-    reg.getCurrentPersistenceContext(emf, props).flush();
+    getPersistenceContext(true).flush();
   }
 
   public Object getDelegate()
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).getDelegate();
+    return getPersistenceContext(false).getDelegate();
   }
 
   public FlushModeType getFlushMode()
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).getFlushMode();
+    return getPersistenceContext(false).getFlushMode();
   }
 
   public <T> T getReference(Class<T> arg0, Object arg1)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).getReference(arg0, arg1);
+    return getPersistenceContext(false).getReference(arg0, arg1);
   }
 
   public EntityTransaction getTransaction()
@@ -136,74 +168,95 @@
     //This should be a no-op for a JTA entity manager
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void lock(Object arg0, LockModeType arg1)
   {
-    reg.getCurrentPersistenceContext(emf, props).lock(arg0, arg1);
+    getPersistenceContext(true).lock(arg0, arg1);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public <T> T merge(T arg0)
   {
-    return reg.getCurrentPersistenceContext(emf, props).merge(arg0);
+    return getPersistenceContext(true).merge(arg0);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void persist(Object arg0)
   {
-    reg.getCurrentPersistenceContext(emf, props).persist(arg0);
+    getPersistenceContext(true).persist(arg0);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void refresh(Object arg0)
   {
-    reg.getCurrentPersistenceContext(emf, props).refresh(arg0);
+    getPersistenceContext(true).refresh(arg0);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void remove(Object arg0)
   {
-    reg.getCurrentPersistenceContext(emf, props).remove(arg0);
+    getPersistenceContext(true).remove(arg0);
   }
 
   public void setFlushMode(FlushModeType arg0)
   {
-    reg.getCurrentOrDetachedPersistenceContext(emf, props).setFlushMode(arg0);
+    getPersistenceContext(false).setFlushMode(arg0);
   }
 
   public <T> TypedQuery<T> createNamedQuery(String arg0, Class<T> arg1)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createNamedQuery(arg0, arg1);
+    return getPersistenceContext(false).createNamedQuery(arg0, arg1);
   }
 
   public <T> TypedQuery<T> createQuery(CriteriaQuery<T> arg0)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createQuery(arg0);
+    return getPersistenceContext(false).createQuery(arg0);
   }
 
   public <T> TypedQuery<T> createQuery(String arg0, Class<T> arg1)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).createQuery(arg0, arg1);
+    return getPersistenceContext(false).createQuery(arg0, arg1);
   }
 
   public void detach(Object arg0)
   {
-    reg.getCurrentOrDetachedPersistenceContext(emf, props).detach(arg0);
+    getPersistenceContext(false).detach(arg0);
   }
 
   public <T> T find(Class<T> arg0, Object arg1, Map<String, Object> arg2)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).find(arg0, arg1, arg2);
+    return getPersistenceContext(false).find(arg0, arg1, arg2);
   }
 
+  /**
+   * @throws TransactionRequiredException if lock mode is not NONE
+   */
   public <T> T find(Class<T> arg0, Object arg1, LockModeType arg2)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).find(arg0, arg1, arg2);
+    return getPersistenceContext(arg2 != LockModeType.NONE).find(arg0, arg1, arg2);
   }
 
+  /**
+   * @throws TransactionRequiredException if lock mode is not NONE
+   */
   public <T> T find(Class<T> arg0, Object arg1, LockModeType arg2, Map<String, Object> arg3)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).find(arg0, arg1, arg2, arg3);
+    return getPersistenceContext(arg2 != LockModeType.NONE).find(arg0, arg1, arg2, arg3);
   }
 
   public CriteriaBuilder getCriteriaBuilder()
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).getCriteriaBuilder();
+    return getPersistenceContext(false).getCriteriaBuilder();
   }
 
   public EntityManagerFactory getEntityManagerFactory()
@@ -211,56 +264,66 @@
     return emf;
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public LockModeType getLockMode(Object arg0)
   {
-    return reg.getCurrentPersistenceContext(emf, props).getLockMode(arg0);
+    return getPersistenceContext(true).getLockMode(arg0);
   }
 
   public Metamodel getMetamodel()
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).getMetamodel();
+    return getPersistenceContext(false).getMetamodel();
   }
 
   public Map<String, Object> getProperties()
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).getProperties();
+    return getPersistenceContext(false).getProperties();
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void lock(Object arg0, LockModeType arg1, Map<String, Object> arg2)
   {
-    reg.getCurrentPersistenceContext(emf, props).lock(arg0, arg1, arg2);
+    getPersistenceContext(true).lock(arg0, arg1, arg2);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void refresh(Object arg0, Map<String, Object> arg1)
   {
-    reg.getCurrentPersistenceContext(emf, props).refresh(arg0, arg1);
+    getPersistenceContext(true).refresh(arg0, arg1);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void refresh(Object arg0, LockModeType arg1)
   {
-    reg.getCurrentPersistenceContext(emf, props).refresh(arg0, arg1);
+    getPersistenceContext(true).refresh(arg0, arg1);
   }
 
+  /**
+   * @throws TransactionRequiredException
+   */
   public void refresh(Object arg0, LockModeType arg1, Map<String, Object> arg2)
   {
-    reg.getCurrentPersistenceContext(emf, props).refresh(arg0, arg1, arg2);
+    getPersistenceContext(true).refresh(arg0, arg1, arg2);
   }
 
   public void setProperty(String arg0, Object arg1)
-  {    
+  {
     /*
-     * TODO: check this
-     * We don't update props because the changed property should only be visible to the 
-     * EntityManager of the current transaction !?
+     * TODO check whether we need to change the properies as well
      */
-    EntityManager em = reg.getCurrentOrNoPersistenceContext(emf, props);
-    if (em != null) {
-      em.setProperty(arg0, arg1);
-    }
+    getPersistenceContext(false).setProperty(arg0, arg1);
   }
 
   public <T> T unwrap(Class<T> arg0)
   {
-    return reg.getCurrentOrDetachedPersistenceContext(emf, props).unwrap(arg0);
+    return getPersistenceContext(false).unwrap(arg0);
   }
 }

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java?rev=906152&r1=906151&r2=906152&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java Wed Feb  3 17:54:18 2010
@@ -72,6 +72,7 @@
     if(transactionKey == null) {
       throw new TransactionRequiredException();
     }
+    
     //Get hold of the Map. If there is no Map already registered then add one.
     //We don't need to worry about a race condition, as no other thread will
     //share our transaction
@@ -104,43 +105,13 @@
   }
   
   /**
-   * Get the persistence context for the current transaction if a transaction is active. 
-   * {@link getCurrentPersistenceContext}
-   * 
-   * Otherwise return a freshly created persistence context that is not associated with any
-   * transaction.
-   * 
-   * @param persistenceUnit
-   * @param properties
-   * @return An {@link EntityManager} object
-   */
-  public EntityManager getCurrentOrDetachedPersistenceContext(EntityManagerFactory persistenceUnit, Map<?,?> properties) 
-  {
-    if (tranRegistry.getTransactionKey() != null)
-      return getCurrentPersistenceContext(persistenceUnit, properties);
-    else 
-      return persistenceUnit.createEntityManager(properties);
-  }
-
-  
-  /**
-   * Get the persistence context for the current transaction if a transaction is active. 
-   * {@link getCurrentPersistenceContext}
-   * 
-   * Otherwise return null;
-   * 
-   * @param persistenceUnit
-   * @param properties
-   * @return The {@link EntityManager} object or null if there is no active transaction.
+   * Determine whether there is an active transaction on the thread
+   * @return
    */
-  public EntityManager getCurrentOrNoPersistenceContext(EntityManagerFactory persistenceUnit, Map<?,?> properties) 
+  public boolean isTransactionActive()
   {
-    if (tranRegistry.getTransactionKey() != null)
-      return getCurrentPersistenceContext(persistenceUnit, properties);
-    else 
-      return null;
+    return tranRegistry.getTransactionKey() != null;
   }
-
   
   /**
    * Provide a {@link TransactionSynchronizationRegistry} to use

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManagerTest.java?rev=906152&r1=906151&r2=906152&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManagerTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/impl/PersistenceContextManagerTest.java Wed Feb  3 17:54:18 2010
@@ -20,14 +20,15 @@
 
 import static java.lang.Boolean.TRUE;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
 import java.util.HashMap;
 import java.util.Hashtable;
 
-import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 
 import org.apache.aries.jpa.container.PersistenceUnitConstants;
+import org.apache.aries.jpa.container.context.namespace.NSHandler;
 import org.apache.aries.mocks.BundleContextMock;
 import org.apache.aries.mocks.BundleMock;
 import org.apache.aries.unittest.mocks.Skeleton;
@@ -87,7 +88,7 @@
     
     reg1 = registerUnit(emf1, unitName, TRUE);
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
     
     mgr.registerContext(unitName, client1, new HashMap<String, Object>());
     
@@ -106,7 +107,7 @@
     testUnitThenContext();
     mgr.unregisterContext("unit", client1);
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
   }
   
   /**
@@ -121,7 +122,7 @@
     testUnitThenContext();
     reg1.unregister();
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
   }
   
   /**
@@ -137,7 +138,7 @@
     
     mgr.registerContext(unitName, client1, new HashMap<String, Object>());
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
     
     reg1 = registerUnit(emf1, unitName, TRUE);
     
@@ -156,7 +157,7 @@
     testContextThenUnit();
     mgr.unregisterContext("unit", client1);
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
   }
   
   /**
@@ -171,7 +172,7 @@
     testContextThenUnit();
     reg1.unregister();
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
   }
   
   /**
@@ -179,15 +180,15 @@
    * context don't match
    */
   @Test
-  public void testAddDifferentContext()
+  public void testAddDifferentContext() throws InvalidSyntaxException
   {
     reg1 = registerUnit(emf1, "unit", TRUE);
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
     
     mgr.registerContext("context", client1, new HashMap<String, Object>());
     
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
   }
   
   /**
@@ -223,7 +224,7 @@
     reg1.unregister();
     assertContextRegistered("context");
     reg2.unregister();
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
   }
   
   /**
@@ -242,7 +243,7 @@
     assertContextRegistered("unit");
     
     mgr.unregisterContext("unit", client2);
-    BundleContextMock.assertNoServiceExists(EntityManager.class.getName());
+    assertNoContextRegistered();
   }
   
   
@@ -263,12 +264,18 @@
         EntityManagerFactory.class.getName(), emf, props);
   }
   
+  private void assertNoContextRegistered() throws InvalidSyntaxException {
+    ServiceReference[] refs = context.getServiceReferences(EntityManagerFactory.class.getName(), "("+NSHandler.PROXY_FACTORY_EMF_ATTRIBUTE+"=*)");
+
+    assertNull(refs);
+  }
+  
   private void assertContextRegistered(String name) throws InvalidSyntaxException {
-    BundleContextMock.assertServiceExists(EntityManager.class.getName());
+    BundleContextMock.assertServiceExists(EntityManagerFactory.class.getName());
     
-    ServiceReference[] refs = context.getServiceReferences(EntityManager.class.getName(), null);
+    ServiceReference[] refs = context.getServiceReferences(EntityManagerFactory.class.getName(), "("+NSHandler.PROXY_FACTORY_EMF_ATTRIBUTE+"=*)");
     
-    assertEquals("Too many EntityManagers", 1, refs.length);
+    assertEquals("Too many EntityManagerFactories", 1, refs.length);
     
     assertEquals("Wrong unit name", name, refs[0].getProperty(PersistenceUnitConstants.OSGI_UNIT_NAME));
     

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java?rev=906152&r1=906151&r2=906152&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/namespace/NSHandlerTest.java Wed Feb  3 17:54:18 2010
@@ -19,12 +19,14 @@
 package org.apache.aries.jpa.container.context.namespace;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
-import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.PersistenceContextType;
 import javax.xml.parsers.DocumentBuilder;
@@ -35,6 +37,7 @@
 import org.apache.aries.blueprint.PassThroughMetadata;
 import org.apache.aries.blueprint.container.Parser;
 import org.apache.aries.blueprint.reflect.BeanMetadataImpl;
+import org.apache.aries.blueprint.reflect.RefMetadataImpl;
 import org.apache.aries.blueprint.reflect.ReferenceMetadataImpl;
 import org.apache.aries.jpa.container.context.PersistenceManager;
 import org.apache.aries.unittest.mocks.MethodCall;
@@ -46,6 +49,7 @@
 import org.osgi.service.blueprint.reflect.BeanProperty;
 import org.osgi.service.blueprint.reflect.ComponentMetadata;
 import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -58,9 +62,12 @@
   private PersistenceManager manager;
   private ParserContext parserCtx;
   private Bundle clientBundle;
+  private List<ComponentMetadata> registeredComponents = new ArrayList<ComponentMetadata>();
   
   @Before
   public void setup() throws Exception {
+    registeredComponents.clear();
+    
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     factory.setNamespaceAware(true);
     DocumentBuilder builder = factory.newDocumentBuilder();
@@ -72,15 +79,9 @@
     sut.setManager(manager);
     
     clientBundle = Skeleton.newMock(Bundle.class);
-    
-    PassThroughMetadata bundleMeta =  Skeleton.newMock(PassThroughMetadata.class);
-    Skeleton.getSkeleton(bundleMeta).setReturnValue(
-        new MethodCall(PassThroughMetadata.class, "getObject"), clientBundle);
-    
-    ComponentDefinitionRegistry registry = Skeleton.newMock(ComponentDefinitionRegistry.class);
-    Skeleton.getSkeleton(registry).setReturnValue(
-        new MethodCall(ComponentDefinitionRegistry.class, "getComponentDefinition", "blueprintBundle"), 
-        bundleMeta);
+        
+    ComponentDefinitionRegistry registry = Skeleton.newMock(new ComponentDefinitionRegistryMock(), 
+        ComponentDefinitionRegistry.class);
     
     parserCtx = Skeleton.newMock(new ParserContextMock(), ParserContext.class);
     Skeleton.getSkeleton(parserCtx).setReturnValue(
@@ -97,7 +98,25 @@
     }
     
     public<T extends Metadata> T createMetadata(Class<T> clazz) {
-      return clazz.cast(new ReferenceMetadataImpl());
+      if (clazz.isAssignableFrom(ReferenceMetadata.class))
+        return clazz.cast(new ReferenceMetadataImpl());
+      else if (clazz.isAssignableFrom(RefMetadata.class))
+        return clazz.cast(new RefMetadataImpl());
+      else
+        return clazz.cast(new BeanMetadataImpl());
+    }
+  }
+  
+  private class ComponentDefinitionRegistryMock {
+    public ComponentMetadata getComponentDefinition(String id) {
+      PassThroughMetadata bundleMeta =  Skeleton.newMock(PassThroughMetadata.class);
+      Skeleton.getSkeleton(bundleMeta).setReturnValue(
+          new MethodCall(PassThroughMetadata.class, "getObject"), clientBundle);
+      return bundleMeta;
+    }
+    
+    public void registerComponentDefinition(ComponentMetadata component) {
+      registeredComponents.add(component);
     }
   }
   
@@ -111,9 +130,11 @@
     
     assertEquals("emf", property.getName());
     assertEquals(EntityManagerFactory.class.getName(), reference.getInterface());
-    assertEquals("(osgi.unit.name=myUnit)", reference.getFilter());
+    assertEquals("(&(!(org.apache.aries.jpa.proxy.factory=*))(osgi.unit.name=myUnit))", reference.getFilter());
     
     Skeleton.getSkeleton(manager).assertSkeletonNotCalled();
+    
+    assertTrue(registeredComponents.isEmpty());
   }
   
   @Test
@@ -125,7 +146,10 @@
     ReferenceMetadata reference = (ReferenceMetadata) property.getValue();
     
     assertEquals("emf2", property.getName());
-    assertEquals(NSHandler.EMPTY_UNIT_NAME_FILTER, reference.getFilter());
+    assertEquals("(&(!(org.apache.aries.jpa.proxy.factory=*))"+NSHandler.EMPTY_UNIT_NAME_FILTER+")", 
+        reference.getFilter());
+
+    assertTrue(registeredComponents.isEmpty());
   }
   
   @Test
@@ -137,7 +161,10 @@
     ReferenceMetadata reference = (ReferenceMetadata) property.getValue();
     
     assertEquals("emf3", property.getName());
-    assertEquals(NSHandler.EMPTY_UNIT_NAME_FILTER, reference.getFilter());
+    assertEquals("(&(!(org.apache.aries.jpa.proxy.factory=*))"+NSHandler.EMPTY_UNIT_NAME_FILTER+")",
+        reference.getFilter());
+    
+    assertTrue(registeredComponents.isEmpty());
   }
   
   @Test 
@@ -151,6 +178,8 @@
 
     assertEquals("myid", bean.getId());
     assertEquals(2, bean.getProperties().size());
+    
+    assertTrue(registeredComponents.isEmpty());
   }
 
   @Test
@@ -158,10 +187,15 @@
     Element e = getTestElement("context");
     BeanMetadata bean = 
       (BeanMetadata) sut.decorate(e, Skeleton.newMock(BeanMetadata.class), parserCtx);
-    ReferenceMetadata reference = (ReferenceMetadata) ((BeanProperty) bean.getProperties().get(0)).getValue();
+    BeanMetadata innerBean = (BeanMetadata) ((BeanProperty) bean.getProperties().get(0)).getValue();
+
+    assertEquals("createEntityManager", innerBean.getFactoryMethod());
+
+    assertEquals(1, registeredComponents.size());
+    ReferenceMetadata reference = (ReferenceMetadata) registeredComponents.get(0);
     
-    assertEquals(EntityManager.class.getName(), reference.getInterface());
-    assertEquals("(osgi.unit.name=myUnit)", reference.getFilter());
+    assertEquals(EntityManagerFactory.class.getName(), reference.getInterface());
+    assertEquals("(&(org.apache.aries.jpa.proxy.factory=*)(osgi.unit.name=myUnit))", reference.getFilter());
     
     Map<String,Object> props = new HashMap<String, Object>();
     props.put("type", PersistenceContextType.TRANSACTION);
@@ -174,10 +208,16 @@
     Element e = getTestElement("contextWithProps");
     BeanMetadata bean = 
       (BeanMetadata) sut.decorate(e, Skeleton.newMock(BeanMetadata.class), parserCtx);
-    ReferenceMetadata reference = (ReferenceMetadata) ((BeanProperty) bean.getProperties().get(0)).getValue();
+    BeanMetadata innerBean = (BeanMetadata) ((BeanProperty) bean.getProperties().get(0)).getValue();
+    
+    assertEquals("createEntityManager", innerBean.getFactoryMethod());
     
-    assertEquals(EntityManager.class.getName(), reference.getInterface());
-    assertEquals(NSHandler.EMPTY_UNIT_NAME_FILTER, reference.getFilter());
+    assertEquals(1, registeredComponents.size());
+    ReferenceMetadata reference = (ReferenceMetadata) registeredComponents.get(0);
+    
+    assertEquals(EntityManagerFactory.class.getName(), reference.getInterface());
+    assertEquals("(&(org.apache.aries.jpa.proxy.factory=*)"+NSHandler.EMPTY_UNIT_NAME_FILTER+")", 
+        reference.getFilter());
     
     Map<String,Object> props = new HashMap<String, Object>();
     props.put("type", PersistenceContextType.EXTENDED);