From 88523b8da330ee4e7565c4d909281a5fb91a717e Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 22 Jun 2015 17:04:45 +0200 Subject: [PATCH] DATACMNS-720 - Improved disabling of default transactions. When default transactions get disabled, we now still configure a TransactionInterceptor to make sure explicitly defined transactions are still applied. Previously the interceptor was not registered at all if default transactions were configured to be turned off and thus even explicitly declared transaction configuration was not considered. Related tickets: DATACMNS-656. --- ...sactionalRepositoryFactoryBeanSupport.java | 8 +++---- ...sactionalRepositoryProxyPostProcessor.java | 21 +++++++++++++++++-- ...RepositoryFactoryBeanSupportUnitTests.java | 20 +++++++++++++++--- ...RepositoryProxyPostProcessorUnitTests.java | 7 ++++--- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java b/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java index 387bad44f..2f5f47b4e 100644 --- a/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java @@ -71,10 +71,7 @@ public abstract class TransactionalRepositoryFactoryBeanSupport attributeCache = new ConcurrentHashMap(); private RepositoryInformation repositoryInformation; + private boolean enableDefaultTransactions = true; /** * @param repositoryInformation the repositoryInformation to set @@ -267,6 +273,13 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr this.repositoryInformation = repositoryInformation; } + /** + * @param enableDefaultTransactions the enableDefaultTransactions to set + */ + public void setEnableDefaultTransactions(boolean enableDefaultTransactions) { + this.enableDefaultTransactions = enableDefaultTransactions; + } + /** * Determine the transaction attribute for this method invocation. *

@@ -349,7 +362,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr // Last fallback is the class of the original method. txAtt = findTransactionAttribute(method.getDeclaringClass()); - if (txAtt != null) { + if (txAtt != null || !enableDefaultTransactions) { return txAtt; } } @@ -368,6 +381,10 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr return txAtt; } + if (!enableDefaultTransactions) { + return null; + } + // Fallback to implementation class transaction settings of nothing found // return findTransactionAttribute(method); Method targetClassMethod = repositoryInformation.getTargetClassMethod(method); diff --git a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java index 8c571c9ea..8c6251496 100644 --- a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java @@ -18,6 +18,7 @@ package org.springframework.data.repository.core.support; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import static org.springframework.test.util.ReflectionTestUtils.*; import org.junit.Test; import org.springframework.aop.Advisor; @@ -38,7 +39,7 @@ public class TransactionRepositoryFactoryBeanSupportUnitTests { * @see DATACMNS-656 */ @Test - public void doesNotRegisterTransactionalRepositoryProxyPostProcessorIfConfigured() { + public void disablesDefaultTransactionsIfConfigured() { SampleTransactionalRepositoryFactoryBean factoryBean = new SampleTransactionalRepositoryFactoryBean(); factoryBean.setEnableDefaultTransactions(false); @@ -48,9 +49,22 @@ public class TransactionRepositoryFactoryBeanSupportUnitTests { CrudRepository repository = factoryBean.getObject(); Advisor[] advisors = ((Advised) repository).getAdvisors(); + boolean found = false; - assertThat(advisors.length, is(greaterThanOrEqualTo(2))); - assertThat(advisors[1].getAdvice(), is(not(instanceOf(TransactionInterceptor.class)))); + for (Advisor advisor : advisors) { + + if (advisor.getAdvice() instanceof TransactionInterceptor) { + + found = true; + + TransactionInterceptor interceptor = (TransactionInterceptor) advisor.getAdvice(); + assertThat(getField(interceptor.getTransactionAttributeSource(), "enableDefaultTransactions"), + is((Object) false)); + break; + } + } + + assertThat(found, is(true)); } @SuppressWarnings({ "unchecked", "rawtypes" }) diff --git a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java index 8c38cb7a6..3f89ad5ac 100644 --- a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java @@ -63,18 +63,19 @@ public class TransactionRepositoryProxyPostProcessorUnitTests { @Test(expected = IllegalArgumentException.class) public void rejectsNullBeanFactory() throws Exception { - new TransactionalRepositoryProxyPostProcessor(null, "transactionManager"); + new TransactionalRepositoryProxyPostProcessor(null, "transactionManager", true); } @Test(expected = IllegalArgumentException.class) public void rejectsNullTxManagerName() throws Exception { - new TransactionalRepositoryProxyPostProcessor(beanFactory, null); + new TransactionalRepositoryProxyPostProcessor(beanFactory, null, true); } @Test public void setsUpBasicInstance() throws Exception { - RepositoryProxyPostProcessor postProcessor = new TransactionalRepositoryProxyPostProcessor(beanFactory, "txManager"); + RepositoryProxyPostProcessor postProcessor = new TransactionalRepositoryProxyPostProcessor(beanFactory, "txManager", + true); postProcessor.postProcess(proxyFactory, repositoryInformation); verify(proxyFactory).addAdvice(isA(TransactionInterceptor.class));