diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java index 2de6b3175..08f94cbf9 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java @@ -59,6 +59,7 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware { private static final boolean IS_JAVA_8 = org.springframework.util.ClassUtils.isPresent("java.util.Optional", RepositoryFactorySupport.class.getClassLoader()); + private static final Class TRANSACTION_PROXY_TYPE = getTransactionProxyType(); private final Map repositoryInformationCache = new HashMap(); private final List postProcessors = new ArrayList(); @@ -174,6 +175,10 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware { result.setTarget(target); result.setInterfaces(new Class[] { repositoryInterface, Repository.class }); + if (TRANSACTION_PROXY_TYPE != null) { + result.addInterface(TRANSACTION_PROXY_TYPE); + } + for (RepositoryProxyPostProcessor processor : postProcessors) { processor.postProcess(result, information); } @@ -296,6 +301,21 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware { } + /** + * Returns the TransactionProxy type or {@literal null} if not on the classpath. + * + * @return + */ + private static Class getTransactionProxyType() { + + try { + return org.springframework.util.ClassUtils + .forName("org.springframework.transaction.interceptor.TransactionalProxy", null); + } catch (ClassNotFoundException o_O) { + return null; + } + } + /** * This {@code MethodInterceptor} intercepts calls to methods of the custom implementation and delegates the to it if * configured. Furthermore it resolves method calls to finders and triggers execution of them. You can rely on having diff --git a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java index 3268cedaf..44e6edc59 100644 --- a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.Future; +import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -80,9 +81,8 @@ public class RepositoryFactorySupportUnitTests { Mockito.reset(factory.strategy); - when( - factory.strategy.resolveQuery(Mockito.any(Method.class), Mockito.any(RepositoryMetadata.class), - Mockito.any(NamedQueries.class))).thenReturn(factory.queryOne, factory.queryTwo); + when(factory.strategy.resolveQuery(Mockito.any(Method.class), Mockito.any(RepositoryMetadata.class), + Mockito.any(NamedQueries.class))).thenReturn(factory.queryOne, factory.queryTwo); factory.addQueryCreationListener(listener); factory.addQueryCreationListener(otherListener); @@ -223,6 +223,26 @@ public class RepositoryFactorySupportUnitTests { factory.addRepositoryProxyPostProcessor(null); } + /** + * @see DATACMNS-715, SPR-13109 + */ + @Test + public void addsTransactionProxyInterfaceIfAvailable() throws Exception { + + try { + + Class type = ClassUtils.forName("org.springframework.transaction.interceptor.TransactionalProxy", null); + + SimpleRepository repository = factory.getRepository(SimpleRepository.class); + assertThat(repository, is(instanceOf(type))); + + } catch (ClassNotFoundException o_O) { + Assume.assumeFalse(true); + } + } + + interface SimpleRepository extends Repository {} + interface ObjectRepository extends Repository, ObjectRepositoryCustom { Object findByClass(Class clazz);