Repository: deltaspike Updated Branches: refs/heads/master a4998790a -> 28bcefc88
DELTASPIKE-940 - Avoid reading transactional annotation. Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/28bcefc8 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/28bcefc8 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/28bcefc8 Branch: refs/heads/master Commit: 28bcefc88dc38c27ad6acfe28a46f1810af81c56 Parents: a499879 Author: John D. Ament <johndam...@apache.org> Authored: Sat Aug 12 13:29:40 2017 -0400 Committer: John D. Ament <johndam...@apache.org> Committed: Sat Aug 12 13:29:40 2017 -0400 ---------------------------------------------------------------------- .../api/entitymanager/EntityManagerConfig.java | 2 +- .../entitymanager/EntityManagerMetadata.java | 46 +++++++++++++++----- .../ResourceLocalTransactionStrategy.java | 7 ++- .../transaction/TransactionStrategyHelper.java | 24 ++++++---- .../noentitymanager/TransactionalBean.java | 4 +- .../manual/ManualTransactionBean.java | 4 +- 6 files changed, 63 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/28bcefc8/deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/EntityManagerConfig.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/EntityManagerConfig.java b/deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/EntityManagerConfig.java index 0155916..de451ed 100644 --- a/deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/EntityManagerConfig.java +++ b/deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/EntityManagerConfig.java @@ -32,7 +32,7 @@ import java.lang.annotation.Target; /** * Configure the EntityManager for a specific repository. */ -@Target(ElementType.TYPE) +@Target( { ElementType.TYPE, ElementType.METHOD } ) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited http://git-wip-us.apache.org/repos/asf/deltaspike/blob/28bcefc8/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerMetadata.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerMetadata.java b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerMetadata.java index 1e9b902..2827fd7 100644 --- a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerMetadata.java +++ b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerMetadata.java @@ -27,6 +27,7 @@ import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.persistence.FlushModeType; import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.util.Set; public class EntityManagerMetadata @@ -35,6 +36,7 @@ public class EntityManagerMetadata private Class<? extends Annotation>[] qualifiers; private boolean entityManagerResolverIsNormalScope; private FlushModeType entityManagerFlushMode; + private boolean readOnly = false; public Class<? extends EntityManagerResolver> getEntityManagerResolverClass() { @@ -76,9 +78,36 @@ public class EntityManagerMetadata this.qualifiers = qualifiers; } - public boolean readFrom(Class<?> componentClass, BeanManager beanManager) + public boolean readFrom(AnnotatedElement method, BeanManager beanManager) + { + EntityManagerConfig entityManagerConfig = method.getAnnotation(EntityManagerConfig.class); + boolean processed = false; + processed = processEntityManagerConfig(beanManager, entityManagerConfig); + + Transactional transactional = method.getAnnotation(Transactional.class); + + processed = processTransactional(processed, transactional); + + return processed; + } + + private boolean processTransactional(boolean processed, Transactional transactional) + { + if (transactional != null && this.qualifiers == null) + { + processed = true; + this.setQualifiers(transactional.qualifier()); + } + + if (transactional != null) + { + this.readOnly = transactional.readOnly(); + } + return processed; + } + + private boolean processEntityManagerConfig(BeanManager beanManager, EntityManagerConfig entityManagerConfig) { - EntityManagerConfig entityManagerConfig = componentClass.getAnnotation(EntityManagerConfig.class); boolean processed = false; if (entityManagerConfig != null) { @@ -98,17 +127,12 @@ public class EntityManagerMetadata this.setEntityManagerResolverIsNormalScope(false); } } - - Transactional transactional = componentClass.getAnnotation(Transactional.class); - - if (transactional != null && this.qualifiers == null) - { - processed = true; - this.setQualifiers(transactional.qualifier()); - } - return processed; } + public boolean isReadOnly() + { + return readOnly; + } } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/28bcefc8/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ResourceLocalTransactionStrategy.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ResourceLocalTransactionStrategy.java b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ResourceLocalTransactionStrategy.java index 6f11a8b..defa418 100644 --- a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ResourceLocalTransactionStrategy.java +++ b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ResourceLocalTransactionStrategy.java @@ -38,6 +38,7 @@ import javax.persistence.EntityTransaction; import org.apache.deltaspike.core.api.literal.AnyLiteral; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.jpa.api.transaction.Transactional; +import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerMetadata; import org.apache.deltaspike.jpa.impl.transaction.context.EntityManagerEntry; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.spi.entitymanager.ActiveEntityManagerHolder; @@ -79,6 +80,7 @@ public class ResourceLocalTransactionStrategy implements TransactionStrategy @Override public Object execute(InvocationContext invocationContext) throws Exception { + EntityManagerMetadata metadata = transactionHelper.createEntityManagerMetadata(invocationContext); Transactional transactionalAnnotation = transactionHelper.extractTransactionalAnnotation(invocationContext); Class targetClass = ProxyUtils.getUnproxiedClass(invocationContext.getTarget().getClass()); //see DELTASPIKE-517 @@ -86,7 +88,7 @@ public class ResourceLocalTransactionStrategy implements TransactionStrategy // all the configured qualifier keys Set<Class<? extends Annotation>> emQualifiers = emHolder.isSet() ? new HashSet<Class<? extends Annotation>>(Arrays.asList(Default.class)) : - transactionHelper.resolveEntityManagerQualifiers(transactionalAnnotation, targetClass); + transactionHelper.resolveEntityManagerQualifiers(metadata, targetClass); TransactionBeanStorage transactionBeanStorage = TransactionBeanStorage.getInstance(); @@ -191,7 +193,7 @@ public class ResourceLocalTransactionStrategy implements TransactionStrategy Set<EntityManagerEntry> entityManagerEntryList = transactionBeanStorage.getUsedEntityManagerEntries(); - boolean rollbackOnly = isRollbackOnly(transactionalAnnotation); + boolean rollbackOnly = metadata.isReadOnly() || isRollbackOnly(transactionalAnnotation); if (!rollbackOnly && entityManagerEntryList.size() > 1) { @@ -324,6 +326,7 @@ public class ResourceLocalTransactionStrategy implements TransactionStrategy } //allows to use a custom tx-controller in a custom strategy + @Deprecated // instead, configure read only on the method/class protected boolean isRollbackOnly(Transactional transactionalAnnotation) { return transactionalAnnotation != null && transactionalAnnotation.readOnly(); http://git-wip-us.apache.org/repos/asf/deltaspike/blob/28bcefc8/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionStrategyHelper.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionStrategyHelper.java b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionStrategyHelper.java index 064707c..e6bf768 100644 --- a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionStrategyHelper.java +++ b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionStrategyHelper.java @@ -20,6 +20,8 @@ package org.apache.deltaspike.jpa.impl.transaction; import org.apache.deltaspike.core.util.AnnotationUtils; import org.apache.deltaspike.jpa.api.transaction.Transactional; +import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerMetadata; +import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerRefLookup; import javax.enterprise.context.Dependent; import javax.enterprise.inject.Any; @@ -47,6 +49,9 @@ public class TransactionStrategyHelper implements Serializable @Inject private BeanManager beanManager; + @Inject + private EntityManagerRefLookup entityManagerRefLookup; + /** * <p>This method uses the InvocationContext to scan the @Transactional * interceptor for a manually specified Qualifier.</p> @@ -57,19 +62,14 @@ public class TransactionStrategyHelper implements Serializable * <p>Please note that we will only pickup the first Qualifier on the * injected EntityManager. We also do <b>not</b> parse for binding or * &h#064;NonBinding values. A @Qualifier should not have any parameter at all.</p> - * @param transactionalAnnotation the @Transactional annotation found on the intercepted class + * @param entityManagerMetadata the metadata to locate the entity manager * @param interceptedTargetClass the Class of the intercepted target */ - public Set<Class<? extends Annotation>> resolveEntityManagerQualifiers(Transactional transactionalAnnotation, + public Set<Class<? extends Annotation>> resolveEntityManagerQualifiers(EntityManagerMetadata entityManagerMetadata, Class interceptedTargetClass) { Set<Class<? extends Annotation>> emQualifiers = new HashSet<Class<? extends Annotation>>(); - Class<? extends Annotation>[] qualifierClasses = null; - - if (transactionalAnnotation != null) - { - qualifierClasses = transactionalAnnotation.qualifier(); - } + Class<? extends Annotation>[] qualifierClasses = entityManagerMetadata.getQualifiers(); if (qualifierClasses == null || qualifierClasses.length == 1 && Any.class.equals(qualifierClasses[0]) ) { @@ -148,6 +148,14 @@ public class TransactionStrategyHelper implements Serializable return null; } + EntityManagerMetadata createEntityManagerMetadata(InvocationContext context) + { + EntityManagerMetadata metadata = new EntityManagerMetadata(); + metadata.readFrom(context.getMethod(), beanManager); + metadata.readFrom(context.getMethod().getDeclaringClass(), beanManager); + return metadata; + } + /** * @return the @Transactional annotation from either the method or class * or <code>null</code> if none present. http://git-wip-us.apache.org/repos/asf/deltaspike/blob/28bcefc8/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/TransactionalBean.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/TransactionalBean.java b/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/TransactionalBean.java index 78961aa..3c0b3dc 100644 --- a/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/TransactionalBean.java +++ b/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/TransactionalBean.java @@ -21,6 +21,7 @@ package org.apache.deltaspike.test.jpa.api.transactional.noentitymanager; import javax.enterprise.context.ApplicationScoped; import javax.persistence.EntityManager; +import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerConfig; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; @@ -32,7 +33,8 @@ public class TransactionalBean * This methods requests a transaction for the EntityManager qualified with {@link Second} although there is no * producer for such an {@link EntityManager}. */ - @Transactional(qualifier = Second.class) + @Transactional + @EntityManagerConfig(qualifier = Second.class) public void executeInTransaction() { // no need to do anything http://git-wip-us.apache.org/repos/asf/deltaspike/blob/28bcefc8/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/ManualTransactionBean.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/ManualTransactionBean.java b/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/ManualTransactionBean.java index 077bc7f..76d7c16 100644 --- a/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/ManualTransactionBean.java +++ b/deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/ManualTransactionBean.java @@ -18,6 +18,7 @@ */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.manual; +import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerConfig; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; @@ -44,7 +45,8 @@ public class ManualTransactionBean { } - @Transactional(qualifier = First.class) + @Transactional + @EntityManagerConfig(qualifier = First.class) public void executeInFirstTransaction() { }