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/02/18 15:05:31 UTC
svn commit: r911407 - in
/incubator/aries/trunk/jpa/jpa-container-context/src:
main/java/org/apache/aries/jpa/container/context/
main/java/org/apache/aries/jpa/container/context/transaction/impl/
main/resources/OSGI-INF/blueprint/ test/java/org/apache/...
Author: timothyjward
Date: Thu Feb 18 14:05:31 2010
New Revision: 911407
URL: http://svn.apache.org/viewvc?rev=911407&view=rev
Log:
ARIES-154 : Add warnings and info to logs if no TransactionSynchronizationRegistry service is available
Modified:
incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.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/main/resources/OSGI-INF/blueprint/jpa.xml
incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java
Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java Thu Feb 18 14:05:31 2010
@@ -66,6 +66,12 @@
_logger.debug("Registering bundle {} as a client of persistence unit {} with properties {}.",
new Object[] {client.getSymbolicName() + "_" + client.getVersion(), unitName, properties});
}
+
+ if(!!!registry.jtaIntegrationAvailable())
+ _logger.warn("No JTA integration is currently available. The managed persistence context {} used by the bundle {} will operate " +
+ "with no transaction context and be read only until a JTA Transaction Services implementation is available in" +
+ "the runtime", new Object[] {unitName, client.getSymbolicName() + "_" + client.getVersion()});
+
//Find the framework for this bundle (we may be in a composite)
Bundle frameworkBundle = client.getBundleContext().getBundle(0);
PersistenceContextManager manager = null;
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=911407&r1=911406&r2=911407&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 Thu Feb 18 14:05:31 2010
@@ -32,11 +32,16 @@
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.metamodel.Metamodel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* A <code>PersistenceContextType.TRANSACTION</code> {@link EntityManager} instance
*/
public class JTAEntityManager implements EntityManager {
-
+ /** Logger */
+ private static final Logger _logger = LoggerFactory.getLogger("org.apache.aries.jpa.container.context");
+
/** The {@link EntityManagerFactory} that can create new {@link EntityManager} instances */
private final EntityManagerFactory emf;
/** The map of properties to pass when creating EntityManagers */
@@ -70,6 +75,9 @@
if (reg.isTransactionActive()) {
return reg.getCurrentPersistenceContext(emf, props);
} else {
+ if(!!!reg.jtaIntegrationAvailable() && _logger.isDebugEnabled())
+ _logger.debug("No integration with JTA transactions is available. No transaction context is active.");
+
if (detachedManager == null) {
EntityManager temp = emf.createEntityManager(props);
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=911407&r1=911406&r2=911407&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 Thu Feb 18 14:05:31 2010
@@ -20,6 +20,7 @@
import java.util.IdentityHashMap;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@@ -27,6 +28,7 @@
import javax.transaction.Synchronization;
import javax.transaction.TransactionSynchronizationRegistry;
+import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,6 +63,12 @@
* active transaction, and to register for post-commit cleanup.
*/
private TransactionSynchronizationRegistry tranRegistry;
+
+ /**
+ * A flag to indicate whether the {@link TransactionSynchronizationRegistry} is available.
+ * The initial value is false, as defined by {@link AtomicBoolean#AtomicBoolean()}.
+ */
+ private final AtomicBoolean registryAvailable = new AtomicBoolean();
/**
* Get a PersistenceContext for the current transaction. The persistence context will
@@ -82,7 +90,12 @@
//Throw the error on to the client
if(!!!isTransactionActive()) {
- throw new TransactionRequiredException("No transaction currently active");
+ if(jtaIntegrationAvailable())
+ throw new TransactionRequiredException("No transaction currently active");
+ else {
+ throw new TransactionRequiredException("No JTA transaction services implementation is currently available. As a result the" +
+ " JPA container cannot integrate with JTA transactions.");
+ }
}
EntityManager toReturn = null;
@@ -130,7 +143,7 @@
*/
public final boolean isTransactionActive()
{
- return tranRegistry.getTransactionKey() != null;
+ return registryAvailable.get() && tranRegistry.getTransactionKey() != null;
}
/**
@@ -142,6 +155,43 @@
}
/**
+ * Returns true if we have access to a {@link TransactionSynchronizationRegistry} and
+ * can manage persistence contexts
+ * @return
+ */
+ public final boolean jtaIntegrationAvailable()
+ {
+ return registryAvailable.get();
+ }
+
+ /**
+ * Called by the blueprint container to indicate that a new {@link TransactionSynchronizationRegistry}
+ * will be used by the runtime
+ * @param ref
+ */
+ public final void addRegistry(ServiceReference ref) {
+ boolean oldValue = registryAvailable.getAndSet(true);
+ if(oldValue) {
+ _logger.warn("The TransactionSynchronizationRegistry used to manage persistence contexts has been replaced." +
+ " The new TransactionSynchronizationRegistry, {}, will now be used to manage persistence contexts." +
+ " Managed persistence contexts may not work correctly unless the runtime uses the new JTA Transaction services implementation" +
+ " to manage transactions.", new Object[] {ref});
+ } else {
+ _logger.info("A TransactionSynchronizationRegistry service is now available in the runtime. Managed persistence contexts will now" +
+ "integrate with JTA transactions using {}.", new Object[] {ref});
+ }
+ }
+
+ public final void removeRegistry(ServiceReference ref) {
+ registryAvailable.set(false);
+ _logger.warn("The TransactionSynchronizationRegistry used to manage persistence contexts is no longer available." +
+ " Managed persistence contexts will no longer be able to integrate with JTA transactions, and will behave as if" +
+ " no there is no transaction context at all times until a new TransactionSynchronizationRegistry is available." +
+ " Applications using managed persistence contexts may not work correctly until a new JTA Transaction services" +
+ " implementation is available.");
+ }
+
+ /**
* This class is used to close EntityManager instances once the transaction has committed,
* and clear the persistenceContextRegistry of old persistence contexts.
*/
Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml Thu Feb 18 14:05:31 2010
@@ -37,7 +37,9 @@
<bean id="JtaPersistenceContextRegistry"
class="org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry">
<property name="tranRegistry">
- <reference interface="javax.transaction.TransactionSynchronizationRegistry" availability="optional" />
+ <reference interface="javax.transaction.TransactionSynchronizationRegistry" availability="optional">
+ <reference-listener ref="JtaPersistenceContextRegistry" bind-method="addRegistry" unbind-method="removeRegistry"/>
+ </reference>
</property>
</bean>
Modified: incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java Thu Feb 18 14:05:31 2010
@@ -20,6 +20,8 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.HashMap;
@@ -28,6 +30,7 @@
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
+import javax.persistence.TransactionRequiredException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.TransactionSynchronizationRegistry;
@@ -129,6 +132,19 @@
contexts = new JTAPersistenceContextRegistry();
contexts.setTranRegistry(Skeleton.newMock(reg, TransactionSynchronizationRegistry.class));
+ contexts.addRegistry(null);
+ }
+
+ @Test
+ public void testIsTranActive()
+ {
+ reg.setTransactionKey(null);
+
+ assertFalse(contexts.isTransactionActive());
+
+ reg.setTransactionKey("");
+
+ assertTrue(contexts.isTransactionActive());
}
@Test
@@ -202,7 +218,41 @@
Skeleton.getSkeleton(em1b).assertCalledExactNumberOfTimes(new MethodCall(EntityManager.class, "close"), 1);
Skeleton.getSkeleton(em2a).assertCalledExactNumberOfTimes(new MethodCall(EntityManager.class, "close"), 1);
Skeleton.getSkeleton(em2b).assertCalledExactNumberOfTimes(new MethodCall(EntityManager.class, "close"), 1);
+ }
+
+ @Test
+ public void testNoTranSyncRegistry() {
+ JTAPersistenceContextRegistry registry = new JTAPersistenceContextRegistry();
+ //blueprint will still call our setter
+ TransactionSynchronizationRegistry tranSyncReg = Skeleton.newMock(reg, TransactionSynchronizationRegistry.class);
+ registry.setTranRegistry(tranSyncReg);
+ reg.setTransactionKey(null);
+
+ assertFalse(registry.jtaIntegrationAvailable());
+ assertFalse(registry.isTransactionActive());
+
+ Skeleton.getSkeleton(tranSyncReg).assertSkeletonNotCalled();
+
+ reg.setTransactionKey("");
+
+ assertFalse(registry.jtaIntegrationAvailable());
+ assertFalse(registry.isTransactionActive());
+
+ Skeleton.getSkeleton(tranSyncReg).assertSkeletonNotCalled();
+ }
+
+ @Test(expected=TransactionRequiredException.class)
+ public void testGetNoTran() {
+ reg.setTransactionKey(null);
+ contexts.getCurrentPersistenceContext(emf1, props1);
+ }
+
+ @Test(expected=TransactionRequiredException.class)
+ public void testGetNoTranSyncRegistry() {
+ reg.setTransactionKey("");
+ contexts.removeRegistry(null);
+ contexts.getCurrentPersistenceContext(emf1, props1);
}
}