2016-10-27 4 views
1

Я хочу понять шаблон Generic Repository. У меня есть общий интерфейс службы, который реализуется абстрактным сервисом, который расширяется всеми реализациями служб. Я хочу, чтобы все операции CRUD и поиск по критериям/спецификациям происходили в абстрактной службе.Данные весны: репозиторий JPA в абстрактной базовой службе для вызова findAll со спецификацией

Все мои репозитории - это интерфейсы, расширяющие JpaRepository и JpaSpecificationExecutor. Тем не менее, я не могу выполнить findAll (спецификация, доступный на странице), используя автообновленный репозиторий в абстрактной службе.

Какие изменения следует внести в структуру, чтобы я мог использовать методы JpaSpecificationExecutor?

служба Интерфейс:

public interface GenericFoo<T, S> { 
    public List<T> search(S criteria, Pageable pageable) { 
} 

Абстрактный сервис:

public abstract class Foo<T, S> implements GenericFoo<T, S> { 
    @Autowired 
    private JpaRepository<T, Long> repository; 

    public List<T> search(S criteria, Pageable pageable) { 
     //throws compilation error 
     repository.findAll(getSpecification(criteria), pageable); 
    } 

    protected abstract Specification<T> getSpecification(S criteria); 
} 

ServiceImpl:

@Component 
@Transactional 
public class BarServiceImpl extends Foo<Bar, BarSearchCriteria> implements GenericFoo { 

    protected Specification<Bar> getSpecification(BarSearchCriteria criteria) { 
     //implementation to be filled for each service 
     return null; 
    } 
} 

Repository:

public interface BarRepository extends JpaRepository<Bar, Long>, JpaSpecificationExecutor<Bar> { 
} 

EDIT: Я также пробовал следующее, хотя ошибка компиляции уходит, но приложение не запускается из-за исключений Autowiring.

SimpleJpaRepository:

public interface SimpleRepository<T> extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> { 
} 

BaseService:

public abstract class BaseService<T, S> implements GenericService<T, S> { 
    @Autowired 
    private SimpleJpaRepository<T, Long> simpleJpaRepository; 

    public List<T> search(S criteria, Pageable pageable) { 
     repository.findAll(getSpecification(criteria), pageable); 
    } 

    protected abstract Specification<T> getSpecification(S criteria); 
} 

Repository:

public interface BarRepository extends SimpleJpaRepository<Bar, Long> { 
} 

StackTrace:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.jpa.repository.support.SimpleJpaRepository com.foopackage.barpackage.services.BaseService.simpleJpaRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.jpa.repository.support.SimpleJpaRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) ~[spring-beans-4.2.8.RELEASE.jar:4.2.8.RELEASE] 
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.8.RELEASE.jar:4.2.8.RELEASE] 
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.8.RELEASE.jar:4.2.8.RELEASE] 
... 22 common frames omitted 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.jpa.repository.support.SimpleJpaRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1380) ~[spring-beans-4.2.8.RELEASE.jar:4.2.8.RELEASE] 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126) ~[spring-beans-4.2.8.RELEASE.jar:4.2.8.RELEASE] 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1021) ~[spring-beans-4.2.8.RELEASE.jar:4.2.8.RELEASE] 
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) ~[spring-beans-4.2.8.RELEASE.jar:4.2.8.RELEASE] 
... 24 common frames omitted 
+0

Какая ошибка компиляции вы получаете? – aviad

+0

@avid - «невозможно разрешить метод» findAll (спецификация , Pageable) », и это немного очевидно, потому что если вы проверяете источник JpaRepository, то он не содержит вышеуказанную подпись. Эти сигнатуры методов являются частью JpaSpecificationExecutor. – mancoolgunda

ответ

0

Какие изменения следует внести в структуру, чтобы я мог использовать методы JpaSpecificationExecutor?

Создание и использование промежуточного интерфейса, как это следует сделать трюк:

public interface RepositoryWithExecutor<T> extends JpaRepository<T, Long>, JpaSpecificationExecutor<Bar> {} 

Теперь ваш BarRepository просто расширяет RepositoryWithExecutor<Bar>

И хранилище Foo<T> должно также быть RepositoryWithExecutor<T>

Обновлено, чтобы ответить на измененный вопрос

Вы пытаетесь autowire поля типа SimpleJpaRepository<T, Long>, но все ваши ApplicationContext знают это BarRepository, который является SimpleJpaRepository<Bar, Long>

Вы должны либо родовая реализацией SimpleJpaRepository<T, Long> или вы должны создавать специализированные версии BaseService, что имеет T специализируется на Bar и ссылается на эту специализированную версию.

Боковое примечание: я не думаю, что вы на самом деле показываете код, который используете, потому что BaseService является абстрактным, а Spring не должен пытаться его создать.

+0

@ jens-schauder- \t Я пробовал то, что вы сказали, и это бросало исключение для аутсорсинга. Для получения более подробной информации, пожалуйста, проверьте изменения. – mancoolgunda