Browse Source

DATACMNS-620 - Repositories now creates reflective RepositoryInvokers for repositories with redeclared CRUD methods.

If repository interfaces redeclare CRUD methods we need to use a ReflectionRepositoryInvoker rather than the CRUD one to make sure we pick up the customizations applied to the method declaration (e.g. caching or transaction annotations).

This is already fixed in master due to the move to the Spring Data REST RepositoryInvoker API.
pull/126/head
Oliver Gierke 11 years ago
parent
commit
f02babd3f8
  1. 24
      src/main/java/org/springframework/data/repository/support/Repositories.java
  2. 21
      src/test/java/org/springframework/data/repository/support/RepositoriesIntegrationTests.java

24
src/main/java/org/springframework/data/repository/support/Repositories.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.data.repository.support;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@ -29,6 +31,7 @@ import org.springframework.data.mapping.PersistentEntity; @@ -29,6 +31,7 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.core.CrudInvoker;
import org.springframework.data.repository.core.CrudMethods;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.support.RepositoryFactoryInformation;
@ -202,7 +205,7 @@ public class Repositories implements Iterable<Class<?>> { @@ -202,7 +205,7 @@ public class Repositories implements Iterable<Class<?>> {
Assert.notNull(repository, String.format("No repository found for domain class: %s", domainClass));
if (repository instanceof CrudRepository) {
if (repository instanceof CrudRepository && !hasRedeclaredCrudMethods(domainClass)) {
return new CrudRepositoryInvoker<T>((CrudRepository<T, Serializable>) repository);
} else {
return new ReflectionRepositoryInvoker<T>(repository, getRepositoryInformationFor(domainClass).getCrudMethods());
@ -217,6 +220,25 @@ public class Repositories implements Iterable<Class<?>> { @@ -217,6 +220,25 @@ public class Repositories implements Iterable<Class<?>> {
return repositoryFactoryInfos.keySet().iterator();
}
/**
* Returns whether any of the CRUD methods of the repository for the given domain type are redeclared.
*
* @param type must not be {@literal null}.
* @return
*/
private boolean hasRedeclaredCrudMethods(Class<?> type) {
CrudMethods crudMethods = getRepositoryInformationFor(type).getCrudMethods();
for (Method method : Arrays.asList(crudMethods.getFindOneMethod(), crudMethods.getSaveMethod())) {
if (!method.getDeclaringClass().equals(CrudRepository.class)) {
return true;
}
}
return false;
}
/**
* Null-object to avoid nasty {@literal null} checks in cache lookups.
*

21
src/test/java/org/springframework/data/repository/support/RepositoriesIntegrationTests.java

@ -78,6 +78,15 @@ public class RepositoriesIntegrationTests { @@ -78,6 +78,15 @@ public class RepositoriesIntegrationTests {
public ProductRepository productRepository() {
return mock(ProductRepository.class);
}
@Bean
public RepositoryFactoryBeanSupport<Repository<Order, Long>, Order, Long> orderRepositoryFactory() {
DummyRepositoryFactoryBean<Repository<Order, Long>, Order, Long> factory = new DummyRepositoryFactoryBean<Repository<Order, Long>, Order, Long>();
factory.setRepositoryInterface(OrderRepository.class);
return factory;
}
}
@Autowired Repositories repositories;
@ -97,6 +106,7 @@ public class RepositoriesIntegrationTests { @@ -97,6 +106,7 @@ public class RepositoriesIntegrationTests {
assertThat(repositories, is(notNullValue()));
assertThat(repositories.getCrudInvoker(User.class), is(instanceOf(CrudRepositoryInvoker.class)));
assertThat(repositories.getCrudInvoker(Product.class), is(instanceOf(ReflectionRepositoryInvoker.class)));
assertThat(repositories.getCrudInvoker(Order.class), is(instanceOf(ReflectionRepositoryInvoker.class)));
}
/**
@ -132,12 +142,19 @@ public class RepositoriesIntegrationTests { @@ -132,12 +142,19 @@ public class RepositoriesIntegrationTests {
}
public static class Product {}
static class Product {}
public static interface ProductRepository extends Repository<Product, Long> {
interface ProductRepository extends Repository<Product, Long> {
Product findOne(Long id);
Product save(Product product);
}
static class Order {}
interface OrderRepository extends CrudRepository<Order, Long> {
Order findOne(Long id);
}
}

Loading…
Cancel
Save