Author: swd847
Date: 2010-07-27 05:07:36 -0400 (Tue, 27 Jul 2010)
New Revision: 13516
Added:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java
Modified:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java
Log:
@TransactionAttribute now works on managed beans
Added:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
===================================================================
---
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
(rev 0)
+++
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.seam.persistence;
+
+import javax.naming.NamingException;
+import javax.persistence.EntityManagerFactory;
+
+import org.jboss.seam.persistence.util.NamingUtils;
+import org.jboss.weld.extensions.core.Veto;
+
+/**
+ * Class that enabled the seam managed persitence context to be configured via
+ * xml.
+ *
+ * There are two ways to do this. Either the persistenceUnintJndi name can be
+ * set, in which case the entityManagerFactory is looked up from JNDI.
+ *
+ * Alternativly the @Inject annotation can be applied to the
+ * entityManagerFactory propery along with any qualifiers needed and the
+ * entityManagerFactory will be injected
+ *
+ * Any qualifiers that are applied to this class are also applied to the managed
+ * persistence context in question
+ *
+ * @author Stuart Douglas
+ *
+ */
+@Veto
+public class ManagedPersistenceContext
+{
+
+ public String getPersistenceUnitJndiName()
+ {
+ return persistenceUnitJndiName;
+ }
+
+ public void setPersistenceUnitJndiName(String persistenceUnitJndiName)
+ {
+ this.persistenceUnitJndiName = persistenceUnitJndiName;
+ }
+
+ public EntityManagerFactory getEntityManagerFactory()
+ {
+ if (entityManagerFactory != null)
+ {
+ return entityManagerFactory;
+ }
+ try
+ {
+ return (EntityManagerFactory)
NamingUtils.getInitialContext().lookup(persistenceUnitJndiName);
+ }
+ catch (NamingException ne)
+ {
+ throw new IllegalArgumentException("EntityManagerFactory not found in JNDI
: " + persistenceUnitJndiName, ne);
+ }
+ }
+
+ public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory)
+ {
+ this.entityManagerFactory = entityManagerFactory;
+ }
+
+ String persistenceUnitJndiName;
+
+ EntityManagerFactory entityManagerFactory;
+
+}
Modified:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java
===================================================================
---
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java 2010-07-27
08:58:14 UTC (rev 13515)
+++
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -22,6 +22,7 @@
package org.jboss.seam.persistence.transaction;
import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
@@ -76,29 +77,35 @@
*/
public <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X>
event)
{
- if (event.getAnnotatedType().isAnnotationPresent(Transactional.class))
+ boolean addInterceptor = false;
+ AnnotatedType<X> type = event.getAnnotatedType();
+ if (type.isAnnotationPresent(Transactional.class))
{
- event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
- return;
+
+ addInterceptor = true;
}
- if (event.getAnnotatedType().isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE)
&& !EjbApi.isEjb(event.getAnnotatedType()))
+ else if (type.isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE) &&
!EjbApi.isEjb(event.getAnnotatedType()))
{
- event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
- return;
+ checkTransactionAttributeIsValue(type, type);
+ addInterceptor = true;
}
- for (AnnotatedMethod<? super X> m : event.getAnnotatedType().getMethods())
+
+ for (AnnotatedMethod<? super X> m : type.getMethods())
{
if (m.isAnnotationPresent(Transactional.class))
{
- event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
- return;
+ addInterceptor = true;
}
else if (m.isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE) &&
!EjbApi.isEjb(event.getAnnotatedType()))
{
- event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
- return;
+ checkTransactionAttributeIsValue(type, m);
+ addInterceptor = true;
}
}
+ if (addInterceptor)
+ {
+ event.setAnnotatedType(addInterceptorBinding(type));
+ }
}
public <X> AnnotatedType addInterceptorBinding(AnnotatedType<X> type)
@@ -109,4 +116,17 @@
});
return builder.create();
}
+
+ private void checkTransactionAttributeIsValue(AnnotatedType type, Annotated element)
+ {
+ Object attribute = element.getAnnotation(EjbApi.TRANSACTION_ATTRIBUTE);
+ if (attribute == EjbApi.REQUIRES_NEW)
+ {
+ throw new RuntimeException("TransactionAttributeType.REQUIRED_NEW is not
supported on Managed Beans that are not EJB's. Annotation was found on type " +
type);
+ }
+ if (attribute == EjbApi.NOT_SUPPORTED)
+ {
+ throw new RuntimeException("TransactionAttributeType.NOT_SUPPORTED is not
supported on Managed Beans that are not EJB's. Annotation was found on type " +
type);
+ }
+ }
}
Modified:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java
===================================================================
---
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java 2010-07-27
08:58:14 UTC (rev 13515)
+++
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -33,6 +33,8 @@
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
+import org.jboss.seam.persistence.util.EjbApi;
+
/**
* Implements transaction propagation rules for Seam JavaBean components.
*
@@ -60,11 +62,52 @@
public TransactionMetadata(AnnotatedElement element)
{
annotationPresent = element.isAnnotationPresent(Transactional.class);
-
if (annotationPresent)
{
propType = element.getAnnotation(Transactional.class).value();
}
+ else if (element.isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE))
+ {
+ annotationPresent = true;
+ Object annotation = element.getAnnotation(EjbApi.TRANSACTION_ATTRIBUTE);
+ try
+ {
+ Object value =
annotation.getClass().getMethod("value").invoke(annotation);
+
+ if (value == EjbApi.REQUIRED)
+ {
+ propType = TransactionPropagation.REQUIRED;
+ }
+ else if (value == EjbApi.MANDATORY)
+ {
+ propType = TransactionPropagation.MANDATORY;
+ }
+ else if (value == EjbApi.NEVER)
+ {
+ propType = TransactionPropagation.NEVER;
+ }
+ else if (value == EjbApi.SUPPORTS)
+ {
+ propType = TransactionPropagation.SUPPORTS;
+ }
+ else if (value == EjbApi.NOT_SUPPORTED)
+ {
+ throw new RuntimeException("TransactionAttributeType.NOT_SUPPORTED
is not allowed on managed beans that are not EJB's. Element: " + element);
+ }
+ else if (value == EjbApi.REQUIRES_NEW)
+ {
+ throw new RuntimeException("TransactionAttributeType.REQUIRES_NEW
is not allowed on managed beans that are not EJB's Element: " + element);
+ }
+ else
+ {
+ throw new RuntimeException("Unkown TransactionAttributeType:
" + value);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
}
public boolean isAnnotationPresent()
Modified:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java
===================================================================
---
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java 2010-07-27
08:58:14 UTC (rev 13515)
+++
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -92,10 +92,8 @@
{
transaction.setRollbackOnly();
}
-
throw e;
}
-
}
public static boolean isRollbackRequired(Exception e, boolean isJavaBean)
Modified:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java
===================================================================
---
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java 2010-07-27
08:58:14 UTC (rev 13515)
+++
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -50,17 +50,17 @@
public static final Class<? extends Annotation> MESSAGE_DRIVEN;
public static final Class<? extends Annotation> SINGLETON;
- private static final Object MANDATORY;
+ public static final Object MANDATORY;
- private static final Object REQUIRED;
+ public static final Object REQUIRED;
- private static final Object REQUIRES_NEW;
+ public static final Object REQUIRES_NEW;
- private static final Object SUPPORTS;
+ public static final Object SUPPORTS;
- private static final Object NOT_SUPPORTED;
+ public static final Object NOT_SUPPORTED;
- private static final Object NEVER;
+ public static final Object NEVER;
public static final boolean INVOCATION_CONTEXT_AVAILABLE;
Added:
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java
===================================================================
---
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java
(rev 0)
+++
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -0,0 +1,131 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.seam.persistence.transactions.test;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TransactionRequiredException;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+
+import junit.framework.Assert;
+
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.seam.persistence.transaction.DefaultTransaction;
+import org.jboss.seam.persistence.transaction.SeamTransaction;
+import org.jboss.seam.persistence.transaction.TransactionExtension;
+import org.jboss.seam.persistence.transaction.TransactionInterceptor;
+import org.jboss.seam.persistence.util.NamingUtils;
+import org.jboss.seam.transactions.test.util.ArtifactNames;
+import org.jboss.seam.transactions.test.util.DontRollBackException;
+import org.jboss.seam.transactions.test.util.EntityManagerProvider;
+import org.jboss.seam.transactions.test.util.Hotel;
+import org.jboss.seam.transactions.test.util.MavenArtifactResolver;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.ByteArrayAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests the @TransactionAttribute interceptor for non ee beans.
+ *
+ * TODO: refactor the tests to share a common superclass
+ *
+ * @author stuart
+ *
+ */
+(a)RunWith(Arquillian.class)
+public class TransactionAttributeInterceptorTest
+{
+ @Deployment
+ public static Archive<?> createTestArchive()
+ {
+
+ WebArchive war =
ShrinkWrap.createDomain().getArchiveFactory().create(WebArchive.class,
"test.war");
+ war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.WELD_EXTENSIONS));
+
war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.SEAM_PERSISTENCE_API));
+ war.addPackage(TransactionExtension.class.getPackage());
+ war.addPackage(NamingUtils.class.getPackage());
+ war.addClasses(TransactionAttributeInterceptorTest.class,
TransactionAttributeManagedBean.class, Hotel.class, EntityManagerProvider.class,
DontRollBackException.class);
+ war.addWebResource("META-INF/persistence.xml",
"classes/META-INF/persistence.xml");
+ war.addWebResource(new
ByteArrayAsset(("<beans><interceptors><class>" +
TransactionInterceptor.class.getName() +
"</class></interceptors></beans>").getBytes()),
"beans.xml");
+
war.addWebResource("META-INF/services/javax.enterprise.inject.spi.Extension",
"classes/META-INF/services/javax.enterprise.inject.spi.Extension");
+ return war;
+ }
+
+ @Inject
+ TransactionAttributeManagedBean bean;
+
+ @Inject
+ @DefaultTransaction
+ SeamTransaction transaction;
+
+ @PersistenceContext
+ EntityManager em;
+
+ @Test
+ public void testTransactionInterceptor() throws NotSupportedException,
SystemException, SecurityException, IllegalStateException, RollbackException,
HeuristicMixedException, HeuristicRollbackException
+ {
+ bean.addHotel();
+ assertHotels(1);
+ try
+ {
+ bean.failToAddHotel();
+ }
+ catch (Exception e)
+ {
+ }
+ assertHotels(1);
+ try
+ {
+ bean.addHotelWithApplicationException();
+ }
+ catch (DontRollBackException e)
+ {
+ }
+ assertHotels(2);
+ }
+
+ @Test(expected = TransactionRequiredException.class)
+ public void testTransactionInterceptorMethodOverrides()
+ {
+ bean.tryAndAddHotelWithNoTransaction();
+ }
+
+ public void assertHotels(int count) throws NotSupportedException, SystemException
+ {
+ transaction.begin();
+ em.joinTransaction();
+ List<Hotel> hotels = em.createQuery("select h from Hotel
h").getResultList();
+ Assert.assertTrue("Wrong number of hotels: " + hotels.size(),
hotels.size() == count);
+ transaction.rollback();
+ }
+}
Added:
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java
===================================================================
---
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java
(rev 0)
+++
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.seam.persistence.transactions.test;
+
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+
+import org.jboss.seam.transactions.test.util.DontRollBackException;
+import org.jboss.seam.transactions.test.util.Hotel;
+
+(a)TransactionAttribute(TransactionAttributeType.REQUIRED)
+public class TransactionAttributeManagedBean
+{
+
+ @Inject
+ EntityManager entityManager;
+
+ public void addHotel()
+ {
+ entityManager.joinTransaction();
+ Hotel h = new Hotel("test", "Fake St", "Wollongong",
"NSW", "2518", "Australia");
+ entityManager.persist(h);
+ entityManager.flush();
+ }
+
+ public void failToAddHotel()
+ {
+ entityManager.joinTransaction();
+ Hotel h = new Hotel("test2", "Fake St", "Wollongong",
"NSW", "2518", "Australia");
+ entityManager.persist(h);
+ entityManager.flush();
+ throw new RuntimeException("Roll back transaction");
+ }
+
+ public void addHotelWithApplicationException() throws DontRollBackException
+ {
+ entityManager.joinTransaction();
+ Hotel h = new Hotel("test3", "Fake St", "Wollongong",
"NSW", "2518", "Australia");
+ entityManager.persist(h);
+ entityManager.flush();
+ throw new DontRollBackException();
+ }
+
+ @TransactionAttribute(TransactionAttributeType.NEVER)
+ public void tryAndAddHotelWithNoTransaction()
+ {
+ entityManager.joinTransaction();
+ Hotel h = new Hotel("test3", "Fake St", "Wollongong",
"NSW", "2518", "Australia");
+ entityManager.persist(h);
+ entityManager.flush();
+ }
+
+}
Modified:
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java
===================================================================
---
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java 2010-07-27
08:58:14 UTC (rev 13515)
+++
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java 2010-07-27
09:07:36 UTC (rev 13516)
@@ -57,6 +57,8 @@
/**
* Tests the @Transactional interceptor
*
+ * TODO: refactor the tests to share a common superclass
+ *
* @author stuart
*
*/
@@ -92,7 +94,6 @@
@Test
public void testTransactionInterceptor() throws NotSupportedException,
SystemException, SecurityException, IllegalStateException, RollbackException,
HeuristicMixedException, HeuristicRollbackException
{
-
bean.addHotel();
assertHotels(1);
try