From ad402dcb4a374628c980ca593203882a6c97c27d Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 22 Nov 2013 16:37:48 +0100 Subject: [PATCH] Status quo for composable stereotypes on interfaces The tests introduced in this commit demonstrate the current lacking support for composable stereotypes on interfaces (using @Transactional) as a concrete example. Issue: SPR-11108 --- ...tationTransactionAttributeSourceTests.java | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java b/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java index b8c6840e52..f552677cd8 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/annotation/AnnotationTransactionAttributeSourceTests.java @@ -23,13 +23,15 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; + import javax.ejb.TransactionAttributeType; import static org.junit.Assert.*; -import org.junit.Test; +import org.junit.Test; import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.ProxyFactory; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.tests.transaction.CallCountingTransactionManager; import org.springframework.transaction.interceptor.NoRollbackRuleAttribute; import org.springframework.transaction.interceptor.RollbackRuleAttribute; @@ -41,6 +43,7 @@ import org.springframework.util.SerializationTestUtils; /** * @author Colin Sampaleanu * @author Juergen Hoeller + * @author Sam Brannen */ public class AnnotationTransactionAttributeSourceTests { @@ -252,6 +255,57 @@ public class AnnotationTransactionAttributeSourceTests { assertTrue(actual.isReadOnly()); } + @Test + public void customClassAttributeWithReadOnlyOverrideOnInterface() throws Exception { + Method method = TestBean9.class.getMethod("getAge", (Class[]) null); + + Transactional annotation = AnnotationUtils.findAnnotation(method, Transactional.class); + assertNull("AnnotationUtils.findAnnotation should not find @Transactional for TestBean9.getAge()", annotation); + annotation = AnnotationUtils.findAnnotation(TestBean9.class, Transactional.class); + assertNotNull("AnnotationUtils.findAnnotation failed to find @Transactional for TestBean9", annotation); + + AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); + TransactionAttribute txAttribute = atas.getTransactionAttribute(method, TestBean9.class); + // SpringTransactionAnnotationParser currently uses + // AnnotatedElementUtils.getAnnotationAttributes() which does not support + // meta-annotations on interfaces. + assertNull("Retrieved TransactionAttribute for TestBean9", txAttribute); + + // RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); + // rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); + // rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); + // assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) + // txAttribute).getRollbackRules()); + // + // assertTrue(txAttribute.isReadOnly()); + } + + @Test + public void customMethodAttributeWithReadOnlyOverrideOnInterface() throws Exception { + Method method = TestBean10.class.getMethod("getAge", (Class[]) null); + + Transactional annotation = AnnotationUtils.findAnnotation(method, Transactional.class); + assertNotNull("AnnotationUtils.findAnnotation failed to find @Transactional for TestBean10.getAge()", + annotation); + annotation = AnnotationUtils.findAnnotation(TestBean10.class, Transactional.class); + assertNull("AnnotationUtils.findAnnotation should not find @Transactional for TestBean10", annotation); + + AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); + TransactionAttribute txAttribute = atas.getTransactionAttribute(method, TestBean10.class); + // SpringTransactionAnnotationParser currently uses + // AnnotatedElementUtils.getAnnotationAttributes() which does not support + // meta-annotations on interfaces. + assertNull("Retrieved TransactionAttribute for TestBean10", txAttribute); + + // RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); + // rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); + // rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); + // assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) + // txAttribute).getRollbackRules()); + // + // assertTrue(txAttribute.isReadOnly()); + } + @Test public void testTransactionAttributeDeclaredOnClassMethodWithEjb3() throws Exception { Method getAgeMethod = ITestBean.class.getMethod("getAge", (Class[]) null); @@ -593,7 +647,35 @@ public class AnnotationTransactionAttributeSourceTests { public static class TestBean8 { + @TxWithAttribute(readOnly = true) + public int getAge() { + return 10; + } + } + + @TxWithAttribute(readOnly = true) + public static interface TestInterface9 { + + public int getAge(); + } + + public static class TestBean9 implements TestInterface9 { + + @Override + public int getAge() { + return 10; + } + } + + public static interface TestInterface10 { + @TxWithAttribute(readOnly=true) + public int getAge(); + } + + public static class TestBean10 implements TestInterface10 { + + @Override public int getAge() { return 10; }