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/12/15 17:57:30 UTC
svn commit: r1049643 - in /incubator/aries/trunk/jpa: ./
jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/
jpa-container-itest/
jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/
jpa-conta...
Author: timothyjward
Date: Wed Dec 15 16:57:29 2010
New Revision: 1049643
URL: http://svn.apache.org/viewvc?rev=1049643&view=rev
Log:
ARIES-451 : Correctly purge the cache for non-transactional EntityManager access
Modified:
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-itest/pom.xml
incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/context/itest/JPAContextTest.java
incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml
incubator/aries/trunk/jpa/pom.xml
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=1049643&r1=1049642&r2=1049643&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 Dec 15 16:57:29 2010
@@ -134,38 +134,80 @@ public class JTAEntityManager implements
public boolean contains(Object arg0)
{
- return getPersistenceContext(false).contains(arg0);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.contains(arg0);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public Query createNamedQuery(String arg0)
{
- return getPersistenceContext(false).createNamedQuery(arg0);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createNamedQuery(arg0);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public Query createNativeQuery(String arg0)
{
- return getPersistenceContext(false).createNativeQuery(arg0);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createNativeQuery(arg0);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
@SuppressWarnings("unchecked")
public Query createNativeQuery(String arg0, Class arg1)
{
- return getPersistenceContext(false).createNativeQuery(arg0, arg1);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createNativeQuery(arg0, arg1);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public Query createNativeQuery(String arg0, String arg1)
{
- return getPersistenceContext(false).createNativeQuery(arg0, arg1);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createNativeQuery(arg0, arg1);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public Query createQuery(String arg0)
{
- return getPersistenceContext(false).createQuery(arg0);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createQuery(arg0);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public <T> T find(Class<T> arg0, Object arg1)
{
- return getPersistenceContext(false).find(arg0, arg1);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.find(arg0, arg1);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
/**
@@ -188,7 +230,13 @@ public class JTAEntityManager implements
public <T> T getReference(Class<T> arg0, Object arg1)
{
- return getPersistenceContext(false).getReference(arg0, arg1);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.getReference(arg0, arg1);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public EntityTransaction getTransaction()
@@ -248,32 +296,66 @@ public class JTAEntityManager implements
public void setFlushMode(FlushModeType arg0)
{
- getPersistenceContext(false).setFlushMode(arg0);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ em.setFlushMode(arg0);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public <T> TypedQuery<T> createNamedQuery(String arg0, Class<T> arg1)
{
- return getPersistenceContext(false).createNamedQuery(arg0, arg1);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createNamedQuery(arg0, arg1);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> arg0)
{
- return getPersistenceContext(false).createQuery(arg0);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createQuery(arg0);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public <T> TypedQuery<T> createQuery(String arg0, Class<T> arg1)
{
- return getPersistenceContext(false).createQuery(arg0, arg1);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.createQuery(arg0, arg1);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public void detach(Object arg0)
{
- getPersistenceContext(false).detach(arg0);
+ EntityManager em = getPersistenceContext(false);
+ //The detatched manager auto-detaches everything, so only
+ //detach from a "real" entity manager
+ if(em != detachedManager)
+ em.detach(arg0);
}
public <T> T find(Class<T> arg0, Object arg1, Map<String, Object> arg2)
{
- return getPersistenceContext(false).find(arg0, arg1, arg2);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.find(arg0, arg1, arg2);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
/**
@@ -281,7 +363,13 @@ public class JTAEntityManager implements
*/
public <T> T find(Class<T> arg0, Object arg1, LockModeType arg2)
{
- return getPersistenceContext(arg2 != LockModeType.NONE).find(arg0, arg1, arg2);
+ EntityManager em = getPersistenceContext(arg2 != LockModeType.NONE);
+ try {
+ return em.find(arg0, arg1, arg2);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
/**
@@ -289,7 +377,13 @@ public class JTAEntityManager implements
*/
public <T> T find(Class<T> arg0, Object arg1, LockModeType arg2, Map<String, Object> arg3)
{
- return getPersistenceContext(arg2 != LockModeType.NONE).find(arg0, arg1, arg2, arg3);
+ EntityManager em = getPersistenceContext(arg2 != LockModeType.NONE);
+ try {
+ return em.find(arg0, arg1, arg2, arg3);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public CriteriaBuilder getCriteriaBuilder()
@@ -354,11 +448,23 @@ public class JTAEntityManager implements
public void setProperty(String arg0, Object arg1)
{
- getPersistenceContext(false).setProperty(arg0, arg1);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ em.setProperty(arg0, arg1);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
public <T> T unwrap(Class<T> arg0)
{
- return getPersistenceContext(false).unwrap(arg0);
+ EntityManager em = getPersistenceContext(false);
+ try {
+ return em.unwrap(arg0);
+ } finally {
+ if(em == detachedManager)
+ em.clear();
+ }
}
}
Modified: incubator/aries/trunk/jpa/jpa-container-itest/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-itest/pom.xml?rev=1049643&r1=1049642&r2=1049643&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-itest/pom.xml (original)
+++ incubator/aries/trunk/jpa/jpa-container-itest/pom.xml Wed Dec 15 16:57:29 2010
@@ -196,6 +196,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.apache.aries.transaction</groupId>
+ <artifactId>org.apache.aries.transaction.wrappers</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.aries.jndi</groupId>
<artifactId>org.apache.aries.jndi.api</artifactId>
<scope>test</scope>
Modified: incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java?rev=1049643&r1=1049642&r2=1049643&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/container/itest/JPAContainerTest.java Wed Dec 15 16:57:29 2010
@@ -15,11 +15,13 @@
*/
package org.apache.aries.jpa.container.itest;
+import static org.ops4j.pax.exam.CoreOptions.bootDelegationPackages;
import static org.ops4j.pax.exam.CoreOptions.equinox;
import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
import static org.ops4j.pax.exam.OptionUtils.combine;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
import javax.persistence.EntityManagerFactory;
@@ -73,7 +75,8 @@ public class JPAContainerTest {
@org.ops4j.pax.exam.junit.Configuration
public static Option[] configuration() {
Option[] options = options(
- bootDelegation(),
+ bootDelegationPackages("javax.transaction", "javax.transaction.*"),
+ vmOption("-Dorg.osgi.framework.system.packages=javax.accessibility,javax.activation,javax.activity,javax.annotation,javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.bmp,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.jws,javax.jws.soap,javax.lang.model,javax.lang.model.element,javax.lang.model.type,javax.lang.model.util,javax.management,javax.management.loading,javax.management.modelmbean,javax.management.monitor,javax.management.openmbean,javax.management.relation,javax.management.remote,javax.management.remote.rmi,javax.management.timer,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.rmi.ssl,javax.script,javax.security.auth,javax.security.auth.callback,
javax.security.auth.kerberos,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.security.sasl,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.plaf.synth,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.tools,javax.xml,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.bind.util,javax.xml.crypto,javax.xml.crypto.dom,javax.xml.crypto.dsig,javax.xml.crypto.dsig.dom,javax.xml.crypto.dsig.keyinfo,javax.xml.crypto.dsig.spec,javax.xml.datatype,javax.xml.name
space,javax.xml.parsers,javax.xml.soap,javax.xml.stream,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax,javax.xml.transform.stream,javax.xml.validation,javax.xml.ws,javax.xml.ws.handler,javax.xml.ws.handler.soap,javax.xml.ws.http,javax.xml.ws.soap,javax.xml.ws.spi,javax.xml.xpath,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.TypeCodePackage,org.omg.CORBA.portable,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.omg.
PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.ServantLocatorPackage,org.omg.PortableServer.portable,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.w3c.dom.bootstrap,org.w3c.dom.css,org.w3c.dom.events,org.w3c.dom.html,org.w3c.dom.ls,org.w3c.dom.ranges,org.w3c.dom.stylesheets,org.w3c.dom.traversal,org.w3c.dom.views,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers,javax.transaction;partial=true;mandatory:=partial,javax.transaction.xa;partial=true;mandatory:=partial"),
// Log
mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
@@ -98,6 +101,8 @@ public class JPAContainerTest {
mavenBundle("org.apache.aries.jndi", "org.apache.aries.jndi.url"),
mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.api"),
mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.container"),
+ mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.manager" ),
+ mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.wrappers" ),
mavenBundle("org.apache.derby", "derby"),
mavenBundle("org.apache.geronimo.specs", "geronimo-jta_1.1_spec"),
mavenBundle("org.apache.geronimo.specs", "geronimo-jpa_2.0_spec"),
Modified: incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/context/itest/JPAContextTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/context/itest/JPAContextTest.java?rev=1049643&r1=1049642&r2=1049643&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/context/itest/JPAContextTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-itest/src/test/java/org/apache/aries/jpa/context/itest/JPAContextTest.java Wed Dec 15 16:57:29 2010
@@ -17,20 +17,40 @@ package org.apache.aries.jpa.context.ite
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.ops4j.pax.exam.CoreOptions.bootDelegationPackages;
import static org.ops4j.pax.exam.CoreOptions.equinox;
import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
import static org.ops4j.pax.exam.OptionUtils.combine;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+import static org.ops4j.pax.exam.CoreOptions.waitForFrameworkStartup;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
import javax.persistence.PersistenceContextType;
+import javax.persistence.Query;
+import javax.persistence.TransactionRequiredException;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.transaction.UserTransaction;
import org.apache.aries.jpa.container.PersistenceUnitConstants;
import org.apache.aries.jpa.container.context.PersistenceContextProvider;
+import org.apache.aries.jpa.container.itest.entities.Car;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.CoreOptions;
@@ -72,23 +92,327 @@ public class JPAContextTest {
//Expected
}
- PersistenceContextProvider provider = getOsgiService(PersistenceContextProvider.class);
+ registerClient("test-unit");
- HashMap<String, Object> props = new HashMap<String, Object>();
- props.put(PersistenceContextProvider.PERSISTENCE_CONTEXT_TYPE, PersistenceContextType.TRANSACTION);
- provider.registerContext("test-unit", bundleContext.getBundle(), props);
+ emf = getProxyEMF("test-unit");
+
+ }
+
+ private EntityManagerFactory getProxyEMF(String name) {
- emf = getOsgiService(EntityManagerFactory.class, "(&(osgi.unit.name=test-unit)("
+ return getOsgiService(EntityManagerFactory.class, "(&(osgi.unit.name=" + name + ")("
+ PersistenceUnitConstants.CONTAINER_MANAGED_PERSISTENCE_UNIT + "=true)" +
"(" + PersistenceContextProvider.PROXY_FACTORY_EMF_ATTRIBUTE + "=*))", DEFAULT_TIMEOUT);
+ }
+
+ @Test
+ public void testTranRequired() throws Exception {
+ registerClient("bp-test-unit");
+
+ EntityManagerFactory emf = getProxyEMF("bp-test-unit");
+
+ final EntityManager managedEm = emf.createEntityManager();
+
+ ensureTREBehaviour(false, managedEm, "contains", new Object());
+ ensureTREBehaviour(false, managedEm, "createNamedQuery", "hi");
+ ensureTREBehaviour(false, managedEm, "createNativeQuery", "hi");
+ ensureTREBehaviour(false, managedEm, "createNativeQuery", "hi", Object.class);
+ ensureTREBehaviour(false, managedEm, "createNativeQuery", "hi", "hi");
+ ensureTREBehaviour(false, managedEm, "createQuery", "hi");
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object());
+ ensureTREBehaviour(true, managedEm, "flush");
+ ensureTREBehaviour(false, managedEm, "getDelegate");
+ ensureTREBehaviour(false, managedEm, "getFlushMode");
+ ensureTREBehaviour(false, managedEm, "getReference", Object.class, new Object());
+ ensureTREBehaviour(true, managedEm, "lock", new Object(), LockModeType.NONE);
+ ensureTREBehaviour(true, managedEm, "merge", new Object());
+ ensureTREBehaviour(true, managedEm, "persist", new Object());
+ ensureTREBehaviour(true, managedEm, "refresh", new Object());
+ ensureTREBehaviour(true, managedEm, "remove", new Object());
+ ensureTREBehaviour(false, managedEm, "setFlushMode", FlushModeType.AUTO);
+ ensureTREBehaviour(false, managedEm, "createNamedQuery", "hi", Object.class);
+ ensureTREBehaviour(false, managedEm, "createQuery", Proxy.newProxyInstance(this.getClass().getClassLoader(),
+ new Class[] {CriteriaQuery.class}, new InvocationHandler() {
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return null;
+ }
+ }));
+ ensureTREBehaviour(false, managedEm, "createQuery", "hi", Object.class);
+ ensureTREBehaviour(false, managedEm, "detach", new Object());
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), new HashMap());
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), LockModeType.NONE);
+ ensureTREBehaviour(true, managedEm, "find", Object.class, new Object(), LockModeType.OPTIMISTIC);
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), LockModeType.NONE,
+ new HashMap());
+ ensureTREBehaviour(true, managedEm, "find", Object.class, new Object(), LockModeType.OPTIMISTIC,
+ new HashMap());
+ ensureTREBehaviour(false, managedEm, "getCriteriaBuilder");
+ ensureTREBehaviour(true, managedEm, "getLockMode", new Object());
+ ensureTREBehaviour(false, managedEm, "getMetamodel");
+ ensureTREBehaviour(false, managedEm, "getProperties");
+ ensureTREBehaviour(true, managedEm, "lock", new Object(), LockModeType.NONE, new HashMap());
+ ensureTREBehaviour(true, managedEm, "refresh", new Object(), new HashMap());
+ ensureTREBehaviour(true, managedEm, "refresh", new Object(), LockModeType.NONE);
+ ensureTREBehaviour(true, managedEm, "refresh", new Object(), LockModeType.NONE, new HashMap());
+ ensureTREBehaviour(false, managedEm, "setProperty", "hi", new Object());
+ ensureTREBehaviour(false, managedEm, "unwrap", Object.class);
+
+ UserTransaction ut = getOsgiService(UserTransaction.class);
+
+ ut.begin();
+ try{
+ ensureTREBehaviour(false, managedEm, "contains", new Object());
+ ensureTREBehaviour(false, managedEm, "createNamedQuery", "hi");
+ ensureTREBehaviour(false, managedEm, "createNativeQuery", "hi");
+ ensureTREBehaviour(false, managedEm, "createNativeQuery", "hi", Object.class);
+ ensureTREBehaviour(false, managedEm, "createNativeQuery", "hi", "hi");
+ ensureTREBehaviour(false, managedEm, "createQuery", "hi");
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object());
+ ensureTREBehaviour(false, managedEm, "flush");
+ ensureTREBehaviour(false, managedEm, "getDelegate");
+ ensureTREBehaviour(false, managedEm, "getFlushMode");
+ ensureTREBehaviour(false, managedEm, "getReference", Object.class, new Object());
+ ensureTREBehaviour(false, managedEm, "lock", new Object(), LockModeType.NONE);
+ ensureTREBehaviour(false, managedEm, "merge", new Object());
+ ensureTREBehaviour(false, managedEm, "persist", new Object());
+ ensureTREBehaviour(false, managedEm, "refresh", new Object());
+ ensureTREBehaviour(false, managedEm, "remove", new Object());
+ ensureTREBehaviour(false, managedEm, "setFlushMode", FlushModeType.AUTO);
+ ensureTREBehaviour(false, managedEm, "createNamedQuery", "hi", Object.class);
+ ensureTREBehaviour(false, managedEm, "createQuery", Proxy.newProxyInstance(this.getClass().getClassLoader(),
+ new Class[] {CriteriaQuery.class}, new InvocationHandler() {
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return null;
+ }
+ }));
+ ensureTREBehaviour(false, managedEm, "createQuery", "hi", Object.class);
+ ensureTREBehaviour(false, managedEm, "detach", new Object());
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), new HashMap());
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), LockModeType.NONE);
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), LockModeType.OPTIMISTIC);
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), LockModeType.NONE,
+ new HashMap());
+ ensureTREBehaviour(false, managedEm, "find", Object.class, new Object(), LockModeType.OPTIMISTIC,
+ new HashMap());
+ ensureTREBehaviour(false, managedEm, "getCriteriaBuilder");
+ ensureTREBehaviour(false, managedEm, "getLockMode", new Object());
+ ensureTREBehaviour(false, managedEm, "getMetamodel");
+ ensureTREBehaviour(false, managedEm, "getProperties");
+ ensureTREBehaviour(false, managedEm, "lock", new Object(), LockModeType.NONE, new HashMap());
+ ensureTREBehaviour(false, managedEm, "refresh", new Object(), new HashMap());
+ ensureTREBehaviour(false, managedEm, "refresh", new Object(), LockModeType.NONE);
+ ensureTREBehaviour(false, managedEm, "refresh", new Object(), LockModeType.NONE, new HashMap());
+ ensureTREBehaviour(false, managedEm, "setProperty", "hi", new Object());
+ ensureTREBehaviour(false, managedEm, "unwrap", Object.class);
+ } finally {
+ ut.rollback();
+ }
+ }
+
+ @Test
+ public void testNonTxEmIsCleared() throws Exception {
+
+ registerClient("bp-test-unit");
+
+ EntityManagerFactory emf = getProxyEMF("bp-test-unit");
+
+ final EntityManager managedEm = emf.createEntityManager();
+
+ UserTransaction ut = getOsgiService(UserTransaction.class);
+
+ ut.begin();
+ try {
+
+ Query q = managedEm.createQuery("DELETE from Car c");
+ q.executeUpdate();
+
+ q = managedEm.createQuery("SELECT Count(c) from Car c");
+ assertEquals(0l, q.getSingleResult());
+
+ Car car = new Car();
+ car.setNumberOfSeats(5);
+ car.setEngineSize(1200);
+ car.setColour("blue");
+ car.setNumberPlate("A1AAA");
+ managedEm.persist(car);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }finally {
+ ut.commit();
+ }
+
+ Car c = managedEm.find(Car.class, "A1AAA");
+
+ assertEquals(5, c.getNumberOfSeats());
+ assertEquals(1200, c.getEngineSize());
+ assertEquals("blue", c.getColour());
+
+ ut.begin();
+ try {
+ Car car = managedEm.find(Car.class, "A1AAA");
+ car.setNumberOfSeats(2);
+ car.setEngineSize(2000);
+ car.setColour("red");
+ } finally {
+ ut.commit();
+ }
+
+ c = managedEm.find(Car.class, "A1AAA");
+
+ assertEquals(2, c.getNumberOfSeats());
+ assertEquals(2000, c.getEngineSize());
+ assertEquals("red", c.getColour());
+
+ }
+
+ @Test
+ public void testNonTxQueries() throws Exception {
+ registerClient("bp-test-unit");
+
+ EntityManagerFactory emf = getProxyEMF("bp-test-unit");
+
+ final EntityManager managedEm = emf.createEntityManager();
+
+ UserTransaction ut = getOsgiService(UserTransaction.class);
+
+ ut.begin();
+ try {
+
+ Query q = managedEm.createQuery("DELETE from Car c");
+ q.executeUpdate();
+
+ q = managedEm.createQuery("SELECT Count(c) from Car c");
+ assertEquals(0l, q.getSingleResult());
+ } finally {
+ ut.commit();
+ }
+
+ Query countQuery = managedEm.createQuery("SELECT Count(c) from Car c");
+ assertEquals(0l, countQuery.getSingleResult());
+
+ ut.begin();
+ try {
+ Car car = new Car();
+ car.setNumberOfSeats(5);
+ car.setEngineSize(1200);
+ car.setColour("blue");
+ car.setNumberPlate("A1AAA");
+ managedEm.persist(car);
+
+ car = new Car();
+ car.setNumberOfSeats(7);
+ car.setEngineSize(1800);
+ car.setColour("green");
+ car.setNumberPlate("B2BBB");
+ managedEm.persist(car);
+ } finally {
+ ut.commit();
+ }
+
+ assertEquals(2l, countQuery.getSingleResult());
+
+ TypedQuery<Car> carQuery = managedEm.
+ createQuery("Select c from Car c ORDER by c.engineSize", Car.class);
+
+ List<Car> list = carQuery.getResultList();
+ assertEquals(2l, list.size());
+
+ assertEquals(5, list.get(0).getNumberOfSeats());
+ assertEquals(1200, list.get(0).getEngineSize());
+ assertEquals("blue", list.get(0).getColour());
+ assertEquals("A1AAA", list.get(0).getNumberPlate());
+
+ assertEquals(7, list.get(1).getNumberOfSeats());
+ assertEquals(1800, list.get(1).getEngineSize());
+ assertEquals("green", list.get(1).getColour());
+ assertEquals("B2BBB", list.get(1).getNumberPlate());
+
+ ut.begin();
+ try {
+ Car car = managedEm.find(Car.class, "A1AAA");
+ car.setNumberOfSeats(2);
+ car.setEngineSize(2000);
+ car.setColour("red");
+
+ car = managedEm.find(Car.class, "B2BBB");
+ managedEm.remove(car);
+
+ car = new Car();
+ car.setNumberOfSeats(2);
+ car.setEngineSize(800);
+ car.setColour("black");
+ car.setNumberPlate("C3CCC");
+ managedEm.persist(car);
+
+ } finally {
+ ut.commit();
+ }
+
+ assertEquals(2l, countQuery.getSingleResult());
+
+ list = carQuery.getResultList();
+ assertEquals(2l, list.size());
+
+ assertEquals(2, list.get(0).getNumberOfSeats());
+ assertEquals(800, list.get(0).getEngineSize());
+ assertEquals("black", list.get(0).getColour());
+ assertEquals("C3CCC", list.get(0).getNumberPlate());
+
+ assertEquals(5, list.get(1).getNumberOfSeats());
+ assertEquals(1200, list.get(1).getEngineSize());
+ assertEquals("blue", list.get(1).getColour());
+ assertEquals("A1AAA", list.get(1).getNumberPlate());
+ }
+
+ private void registerClient(String name) {
+ PersistenceContextProvider provider = getOsgiService(PersistenceContextProvider.class);
+
+ HashMap<String, Object> props = new HashMap<String, Object>();
+ props.put(PersistenceContextProvider.PERSISTENCE_CONTEXT_TYPE, PersistenceContextType.TRANSACTION);
+ provider.registerContext(name, bundleContext.getBundle(), props);
}
+ private void ensureTREBehaviour(boolean expectedToFail, EntityManager em, String methodName, Object... args) throws Exception {
+
+ List<Class> argTypes = new ArrayList<Class>();
+ for(Object o : args) {
+ if(o instanceof Map)
+ argTypes.add(Map.class);
+ else if (o instanceof CriteriaQuery)
+ argTypes.add(CriteriaQuery.class);
+ else
+ argTypes.add(o.getClass());
+ }
+
+ Method m = EntityManager.class.getMethod(methodName,
+ argTypes.toArray(new Class[args.length]));
+
+ try {
+ m.invoke(em, args);
+ if(expectedToFail)
+ fail("A transaction is required");
+ } catch (InvocationTargetException ite) {
+ if(expectedToFail &&
+ !!!(ite.getCause() instanceof TransactionRequiredException))
+ fail("We got the wrong failure. Expected a TransactionRequiredException" +
+ ", got a " + ite.toString());
+ else if (!!!expectedToFail &&
+ ite.getCause() instanceof TransactionRequiredException)
+ fail("We got the wrong failure. Expected not to get a TransactionRequiredException" +
+ ", but we got one anyway!");
+ }
+ }
+
@org.ops4j.pax.exam.junit.Configuration
public static Option[] configuration() {
Option[] options = options(
- bootDelegation(),
-
+ bootDelegationPackages("javax.transaction", "javax.transaction.*"),
+ vmOption("-Dorg.osgi.framework.system.packages=javax.accessibility,javax.activation,javax.activity,javax.annotation,javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.bmp,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.jws,javax.jws.soap,javax.lang.model,javax.lang.model.element,javax.lang.model.type,javax.lang.model.util,javax.management,javax.management.loading,javax.management.modelmbean,javax.management.monitor,javax.management.openmbean,javax.management.relation,javax.management.remote,javax.management.remote.rmi,javax.management.timer,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.rmi.ssl,javax.script,javax.security.auth,javax.security.auth.callback,
javax.security.auth.kerberos,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.security.sasl,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.plaf.synth,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.tools,javax.xml,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.bind.util,javax.xml.crypto,javax.xml.crypto.dom,javax.xml.crypto.dsig,javax.xml.crypto.dsig.dom,javax.xml.crypto.dsig.keyinfo,javax.xml.crypto.dsig.spec,javax.xml.datatype,javax.xml.name
space,javax.xml.parsers,javax.xml.soap,javax.xml.stream,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax,javax.xml.transform.stream,javax.xml.validation,javax.xml.ws,javax.xml.ws.handler,javax.xml.ws.handler.soap,javax.xml.ws.http,javax.xml.ws.soap,javax.xml.ws.spi,javax.xml.xpath,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.TypeCodePackage,org.omg.CORBA.portable,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.omg.
PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.ServantLocatorPackage,org.omg.PortableServer.portable,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.w3c.dom.bootstrap,org.w3c.dom.css,org.w3c.dom.events,org.w3c.dom.html,org.w3c.dom.ls,org.w3c.dom.ranges,org.w3c.dom.stylesheets,org.w3c.dom.traversal,org.w3c.dom.views,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers,javax.transaction;partial=true;mandatory:=partial,javax.transaction.xa;partial=true;mandatory:=partial"),
// Log
mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
mavenBundle("org.ops4j.pax.logging", "pax-logging-service"),
@@ -107,9 +431,14 @@ public class JPAContextTest {
// Adding blueprint to the runtime is a hack to placate the maven bundle plugin.
mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint"),
mavenBundle("org.apache.geronimo.specs", "geronimo-jpa_2.0_spec"),
+ mavenBundle("org.apache.aries.jndi", "org.apache.aries.jndi.api"),
+ mavenBundle("org.apache.aries.jndi", "org.apache.aries.jndi.core"),
+ mavenBundle("org.apache.aries.jndi", "org.apache.aries.jndi.url"),
mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.api"),
mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.container"),
mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.container.context"),
+ mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.manager" ),
+ mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.wrappers" ),
mavenBundle("org.apache.derby", "derby"),
mavenBundle("org.apache.geronimo.specs", "geronimo-jta_1.1_spec"),
mavenBundle("commons-lang", "commons-lang"),
@@ -124,6 +453,9 @@ public class JPAContextTest {
mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.container.itest.bundle"),
+// vmOption ("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006"),
+// waitForFrameworkStartup(),
+
equinox().version("3.5.0"));
options = updateOptions(options);
return options;
Modified: incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml?rev=1049643&r1=1049642&r2=1049643&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml (original)
+++ incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/META-INF/persistence.xml Wed Dec 15 16:57:29 2010
@@ -33,11 +33,17 @@
</properties>
</persistence-unit>
- <persistence-unit name="bp-test-unit" transaction-type="RESOURCE_LOCAL">
+ <persistence-unit name="bp-test-unit" transaction-type="JTA">
<description>Test persistence unit for the JPA Container and Context iTests</description>
<jta-data-source>blueprint:comp/jta</jta-data-source>
<non-jta-data-source>blueprint:comp/nonjta</non-jta-data-source>
<class>org.apache.aries.jpa.container.itest.entities.Car</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
+ <properties>
+ <!-- These properties are creating the database on the fly. We are using them to avoid the tests having
+ to create a database -->
+ <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
+ <property name="openjpa.jdbc.DBDictionary" value="derby"/>
+ </properties>
</persistence-unit>
</persistence>
Modified: incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml?rev=1049643&r1=1049642&r2=1049643&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml (original)
+++ incubator/aries/trunk/jpa/jpa-container-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml Wed Dec 15 16:57:29 2010
@@ -16,11 +16,6 @@
limitations under the License.
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
-
- <bean id="jta" class="org.apache.derby.jdbc.EmbeddedDataSource">
- <property name="databaseName" value="memory:testDB"/>
- <property name="createDatabase" value="create"/>
- </bean>
<bean id="nonjta" class="org.apache.derby.jdbc.EmbeddedDataSource">
<property name="databaseName" value="memory:testDB"/>
@@ -28,7 +23,17 @@
</bean>
- <service ref="jta" interface="javax.sql.DataSource"/>
+ <service interface="javax.sql.XADataSource">
+ <service-properties>
+ <entry key="transactional" value="true"/>
+ </service-properties>
+ <bean class="org.apache.derby.jdbc.EmbeddedXADataSource">
+ <property name="databaseName" value="memory:testDB"/>
+ <property name="createDatabase" value="create"/>
+ </bean>
+ </service>
+ <reference id="jta" availability="optional" interface="javax.sql.DataSource"
+ filter="(transactional=true)"/>
</blueprint>
Modified: incubator/aries/trunk/jpa/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/pom.xml?rev=1049643&r1=1049642&r2=1049643&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/pom.xml (original)
+++ incubator/aries/trunk/jpa/pom.xml Wed Dec 15 16:57:29 2010
@@ -180,6 +180,12 @@
<version>0.3-incubating-SNAPSHOT</version>
</dependency>
<dependency>
+ <groupId>org.apache.aries.transaction</groupId>
+ <artifactId>org.apache.aries.transaction.wrappers</artifactId>
+ <scope>test</scope>
+ <version>0.3-incubating-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.aries.jndi</groupId>
<artifactId>org.apache.aries.jndi.api</artifactId>
<scope>test</scope>