简体   繁体   English

自定义 Jpa 存储库错误,片段实现错误

[英]Custom Jpa Repository erroring with Fragment implementation error

I am currently writing an application in spring boot and am building my own custom repository.我目前正在 spring 启动中编写应用程序,并且正在构建自己的自定义存储库。

First things first, here the code in question:首先,这里有问题的代码:

@Repository
public interface ServiceRepository<T extends ServiceEntity> extends JpaRepository<T, UUID>, ServiceRepositoryCustom {
}

public interface ServiceRepositoryCustom {
    List<ServiceEntity> findAllWithParams(String query);
}

public class ServiceRepositoryImpl implements ServiceRepositoryCustom {

    @PersistenceContext
    EntityManager em;

    @Override
    public List<ServiceEntity> findAllWithParams(String query) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<ServiceEntity> cq = cb.createQuery(ServiceEntity.class);

        Root<ServiceEntity> serviceEntity = cq.from(ServiceEntity.class);
        List<Predicate> predicates = new ArrayList<>();

        if(query != null)  {
            predicates.add(cb.equal(serviceEntity.get("name"), query));
        }
        cq.where(predicates.toArray(predicates.toArray(new Predicate[0])));

        return em.createQuery(cq).getResultList();
    }
}

After launching the application, it fails with following stack trace:启动应用程序后,它失败并显示以下堆栈跟踪:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'Registry' defined in file [/home/awesomedude091/Desktop/ViralManager/Core/build/classes/java/main/com/viralinnovation/viralmanager/Plugins/Registry.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'JVMServiceRepository' defined in com.viralinnovation.viralmanager.Services.Entities.Repositories.JVMServiceRepository defined in @EnableJpaRepositories declared on ViralManagerApplication: Cannot create inner bean '(inner bean)#34cb0e49' of type [org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean] while setting bean property 'repositoryFragments'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#34cb0e49': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceRepositoryImplFragment': Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.repository.core.support.RepositoryFragment]: Factory method 'implemented' threw exception; nested exception is java.lang.IllegalArgumentException: Fragment implementation com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepositoryImpl does not implement com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepository!
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.19.jar:5.3.19]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.19.jar:5.3.19]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.7.jar:2.6.7]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.7.jar:2.6.7]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.7.jar:2.6.7]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.7.jar:2.6.7]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.7.jar:2.6.7]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.7.jar:2.6.7]
    at com.viralinnovation.viralmanager.master.ViralManagerApplication.main(ViralManagerApplication.java:25) ~[main/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'JVMServiceRepository' defined in com.viralinnovation.viralmanager.Services.Entities.Repositories.JVMServiceRepository defined in @EnableJpaRepositories declared on ViralManagerApplication: Cannot create inner bean '(inner bean)#34cb0e49' of type [org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean] while setting bean property 'repositoryFragments'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#34cb0e49': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceRepositoryImplFragment': Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.repository.core.support.RepositoryFragment]: Factory method 'implemented' threw exception; nested exception is java.lang.IllegalArgumentException: Fragment implementation com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepositoryImpl does not implement com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepository!
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:389) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:134) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1707) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1452) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.19.jar:5.3.19]
    ... 23 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#34cb0e49': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceRepositoryImplFragment': Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.repository.core.support.RepositoryFragment]: Factory method 'implemented' threw exception; nested exception is java.lang.IllegalArgumentException: Fragment implementation com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepositoryImpl does not implement com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepository!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:374) ~[spring-beans-5.3.19.jar:5.3.19]
    ... 37 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceRepositoryImplFragment': Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.repository.core.support.RepositoryFragment]: Factory method 'implemented' threw exception; nested exception is java.lang.IllegalArgumentException: Fragment implementation com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepositoryImpl does not implement com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepository!
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean.lambda$afterPropertiesSet$0(RepositoryFragmentsFactoryBean.java:76) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
    at org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean.afterPropertiesSet(RepositoryFragmentsFactoryBean.java:77) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.19.jar:5.3.19]
    ... 40 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.repository.core.support.RepositoryFragment]: Factory method 'implemented' threw exception; nested exception is java.lang.IllegalArgumentException: Fragment implementation com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepositoryImpl does not implement com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepository!
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.19.jar:5.3.19]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.19.jar:5.3.19]
    ... 60 common frames omitted
Caused by: java.lang.IllegalArgumentException: Fragment implementation com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepositoryImpl does not implement com.viralinnovation.viralmanager.Services.Entities.Repositories.ServiceRepository!
    at org.springframework.util.Assert.isTrue(Assert.java:139) ~[spring-core-5.3.19.jar:5.3.19]
    at org.springframework.data.repository.core.support.RepositoryFragment$ImplementedRepositoryFragment.lambda$new$1(RepositoryFragment.java:205) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at java.base/java.util.Optional.ifPresent(Optional.java:178) ~[na:na]
    at org.springframework.data.repository.core.support.RepositoryFragment$ImplementedRepositoryFragment.<init>(RepositoryFragment.java:203) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.data.repository.core.support.RepositoryFragment.implemented(RepositoryFragment.java:67) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.19.jar:5.3.19]
    ... 61 common frames omitted


Process finished with exit code 1

Any help is much appreciated:)任何帮助深表感谢:)

Note: This setup previously worked with a JPA Repository, so it is not the issue of the services calling it, it is the fault of the new Service Repository.注意:此设置以前使用 JPA 存储库,因此不是服务调用它的问题,而是新服务存储库的问题。

The JPA repository scan by default looks for implementations with post fix string for class, which is Impl (it could be changed if you need).默认情况下,JPA 存储库扫描查找具有 class 的后修复字符串的实现,它是Impl (如果需要,可以更改)。

When you want to add custom behaviour to a JPA repository by an 'extension', you need to follow: ExtensionName (interface) -> EntensionNameImpl (class).当您想通过“扩展”向 JPA 存储库添加自定义行为时,您需要遵循:ExtensionName(接口)-> EntensionNameImpl(类)。

In your case ServiceRepositoryImpl implements ServiceRepositoryCustom is wrong, you need to rename ServiceRepositoryImpl to ServiceRepositoryCustomImpl ;在您的情况下ServiceRepositoryImpl implements ServiceRepositoryCustom是错误的,您需要将 ServiceRepositoryImpl 重命名ServiceRepositoryImpl to ServiceRepositoryCustomImpl because in this case Spring expects ServiceRepositoryImpl to be a ServiceRepository因为在这种情况下 Spring 期望ServiceRepositoryImpl是一个ServiceRepository

Take a look on https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations .看看https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

(Off-topic) When you enabled Spring JPA repository scan, you should not need @Repository annotation, because extends JpaRepository marks the interface as repository for you; (题外话)当您启用 Spring JPA 存储库扫描时,您应该不需要@Repository注释,因为extends JpaRepository将接口标记为存储库; if you go look its dependency hierarchy you find a Repository interface on top.如果您 go 查看它的依赖层次结构,您会在顶部找到一个Repository接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM