当前位置: 首页 > 知识库问答 >
问题:

Spring Data:用规范调用findAll的抽象基服务中的JPA存储库

东郭鸿福
2023-03-14

我希望了解通用存储库模式。我有一个由抽象服务实现的通用服务接口,抽象服务由所有服务实现扩展。我希望确保所有CRUD操作和根据标准/规范进行的搜索都发生在抽象服务中。

我的所有存储库都是扩展JpaRepository和JPaspecificationExecutor的接口。但是,我不能在抽象服务中使用autowired存储库执行findAll(规范,分页)。

服务接口

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;
    }  
}
public interface BarRepository extends JpaRepository<Bar, Long>, JpaSpecificationExecutor<Bar> {
}
public interface SimpleRepository<T> extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> {
}
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);
}
public interface BarRepository extends SimpleJpaRepository<Bar, Long> {
}
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

共有1个答案

壤驷麒
2023-03-14

我应该对结构进行哪些更改,以便能够利用JPaspecificationExecutor的方法?

创建和使用类似这样的中间接口应该可以做到这一点:

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

现在,您的BarRepository只需扩展repositorywithexecutor

附注:我认为您实际上并没有显示您正在使用的代码,因为baseService是抽象的,Spring不应该尝试实例化它。

 类似资料:
  • 是否有一种方法可以使通用Spring数据JPA存储库正确处理类似的方法?例如只返回狗,而不返回所有动物?或者至少,最好的变通方法是什么? 它的工作几乎完美,保存每一个动物在自己的桌子上,等等。唯一的问题是:同时返回水豚和狗。这个答案解释说: 这只有在域类使用单表继承时才起作用。我们在引导时能得到的关于domain类的唯一信息是它将是Product对象。因此,对于像findAll()甚至findBy

  • 无法对JpaSpecificationExecutor存储库使用findAll(规范,分页)方法。我将存储库接口设置为: 每当我调用EmployeeRepository.findall(规范,分页)时;抛出此错误: 这是StackTrace: 完整代码:https://github.com/sanketkd/specificationexecutor 存储库:

  • 我按照本教程获得了Spring Data JPA规范:https://dzone.com/articles/using-spring-data-jpa-specification 它为我实现了这一点,但我不能调用规范方法来搜索它们。我想把它们放在我的SearchController中: 现在我想在我的SearchController(比如Controller)中调用这个方法,但我不知道如何调用。目

  • 在任何情况下,我不想重复计数的每一个页面我需要,这个信息是需要的只是第一次调用。

  • 我有jpa存储库: 和客户规范 通常我是这样取记录的 现在我想按组计算 其中(复杂规范中的标准)按字段1、字段2、字段3分组; 如上所述,如何使用jpaRepository和Custom规范执行此GROUP BY和COUNT 注意:我可以像这样做完整计数 帮助我分组和计数。提前谢谢。

  • 我有一个控制器尝试用可选字段搜索。JPA实体类定义为: