You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2010/01/15 14:08:42 UTC
svn commit: r899618 - in /incubator/aries/trunk/jpa/jpa-container-context:
./ src/ src/main/ src/main/java/ src/main/java/org/
src/main/java/org/apache/ src/main/java/org/apache/aries/
src/main/java/org/apache/aries/jpa/ src/main/java/org/apache/aries/...
Author: timothyjward
Date: Fri Jan 15 13:08:41 2010
New Revision: 899618
URL: http://svn.apache.org/viewvc?rev=899618&view=rev
Log: (empty)
Added:
incubator/aries/trunk/jpa/jpa-container-context/
incubator/aries/trunk/jpa/jpa-container-context/pom.xml
incubator/aries/trunk/jpa/jpa-container-context/src/
incubator/aries/trunk/jpa/jpa-container-context/src/main/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java
Added: incubator/aries/trunk/jpa/jpa-container-context/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/pom.xml?rev=899618&view=auto
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/pom.xml (added)
+++ incubator/aries/trunk/jpa/jpa-container-context/pom.xml Fri Jan 15 13:08:41 2010
@@ -0,0 +1,59 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>jpa</artifactId>
+ <groupId>org.apache.aries.jpa</groupId>
+ <version>1.0.0-incubating-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.aries.jpa</groupId>
+ <artifactId>jpa-container-context</artifactId>
+ <name>Aries JPA Container Managed Contexts</name>
+ <packaging>bundle</packaging>
+ <version>1.0.0-incubating-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jpa_2.0_spec</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jta_1.1_spec</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ </dependencies>
+
+
+ <build>
+ <resources>
+ <resource>
+ <targetPath>OSGI-INF/blueprint</targetPath>
+ <filtering>false</filtering>
+ <directory>${basedir}/src/main/resources/OSGI-INF/blueprint</directory>
+ <includes>
+ <include>*.xml</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${pom.groupId}.container</Bundle-SymbolicName>
+ <Export-Package>
+ org.apache.aries.jpa.container.parsing;version="${pom.version}",
+ org.apache.aries.jpa.container;version="${pom.version}"
+ </Export-Package>
+ <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+ <_removeheaders>Ignore-Package,Include-Resource,Private-Package,Bundle-DocURL</_removeheaders>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
Added: 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=899618&view=auto
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java (added)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java Fri Jan 15 13:08:41 2010
@@ -0,0 +1,102 @@
+package org.apache.aries.jpa.container.context.transaction.impl;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.TransactionRequiredException;
+import javax.transaction.Synchronization;
+import javax.transaction.TransactionSynchronizationRegistry;
+
+/**
+ * This class is used to manage the lifecycle of JTA peristence contexts
+ */
+public class JTAPersistenceContextRegistry {
+
+ /**
+ * The transaction synchronization registry, used to determine the currently
+ * active transaction, and to register for post-commit cleanup.
+ */
+ private TransactionSynchronizationRegistry tranRegistry;
+
+ /**
+ * The registry of active persistence contexts. The outer map must be thread safe, as
+ * multiple threads can request persistence contexts. The inner Map does not need to
+ * be thread safe as only one thread can be in a transaction. As a result the inner
+ * Map will never be accessed concurrently.
+ */
+ private final ConcurrentMap<Object, Map<EntityManagerFactory, EntityManager>> persistenceContextRegistry = new ConcurrentHashMap<Object, Map<EntityManagerFactory,EntityManager>>();
+
+ /**
+ * Get a PersistenceContext for the current transaction. The persistence context will
+ * automatically be closed when the transaction completes.
+ *
+ * @param persistenceUnit The peristence unit to create the persitence context from
+ * @param properties Any properties that should be passed on the call to {@code createEntityManager()}
+ *
+ * @return A persistence context associated with the current transaction. Note that this will
+ * need to be wrappered to obey the JPA spec by throwing the correct exceptions
+ * @throws {@link TransactionRequiredException} if there is no active transaction.
+ */
+ public EntityManager getCurrentPersistenceContext(EntityManagerFactory persistenceUnit, Map<?,?> properties)
+ {
+ //There will only ever be one thread associated with a transaction at a given time
+ //As a result, it is only the outer map that needs to be thread safe.
+ Object transactionKey = tranRegistry.getTransactionKey();
+
+ //TODO Globalize and log this problem
+ //Throw the error on to the client
+ 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
+ Map<EntityManagerFactory, EntityManager> contextsForTransaction = persistenceContextRegistry.get(transactionKey);
+
+ //If we need to, create a new Map add it to the registry, and register it for cleanup
+ if(contextsForTransaction == null) {
+ contextsForTransaction = new IdentityHashMap<EntityManagerFactory, EntityManager>();
+ persistenceContextRegistry.put(transactionKey, contextsForTransaction);
+ tranRegistry.registerInterposedSynchronization(new EntityManagerClearUp(transactionKey));
+ }
+
+ //Still only one thread for this transaction, so don't worry about any race conditions
+ EntityManager toReturn = contextsForTransaction.get(persistenceUnit);
+
+ if(toReturn == null) {
+ toReturn = (properties == null) ? persistenceUnit.createEntityManager() : persistenceUnit.createEntityManager(properties);
+ contextsForTransaction.put(persistenceUnit, toReturn);
+ }
+
+ return toReturn;
+ }
+
+ /**
+ * This class is used to close EntityManager instances once the transaction has committed,
+ * and clear the persistenceContextRegistry of old persistence contexts.
+ */
+ private class EntityManagerClearUp implements Synchronization {
+
+ private final Object key;
+
+ public EntityManagerClearUp(Object transactionKey) {
+ key = transactionKey;
+ }
+
+ public void afterCompletion(int arg0) {
+ Map<EntityManagerFactory, EntityManager> tidyUp = persistenceContextRegistry.remove(key);
+ if(tidyUp != null) {
+ for(EntityManager em : tidyUp.values())
+ em.close();
+ }
+ }
+
+ public void beforeCompletion() {
+ //This is a no-op;
+ }
+ }
+}