简体   繁体   中英

Spring DatastoreRepository beans cannot be resolved at runtime, but Intellij shows no errors when building

I have been migrating a project to use Spring DataStore Repositories from the awful manual implementation. A POC was run, and everything was fine.

However, when I replaced the old repository packages with the new ones, I am getting the following dependency error when I try to run the application:

2019-10-23 15:46:20.409 DEBUG 8416 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : Application failed to start due to an exception

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ps_test_tool_datastore.repos.user_repos.RoleRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1695) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1253) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:874) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:778) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:226) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1358) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:397) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1429) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at ps_test_tool_datastore.Application.main(Application.java:16) [classes/:na]

2019-10-23 15:46:20.409 ERROR 8416 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in ps_test_tool_datastore.services.user_services.RoleServices required a bean of type 'ps_test_tool_datastore.repos.user_repos.RoleRepository' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'ps_test_tool_datastore.repos.user_repos.RoleRepository' in your configuration.


Process finished with exit code 1

Underlying Object:

package ps_test_tool_datastore.repos.pojos.user_info;

import org.springframework.cloud.gcp.data.datastore.core.mapping.Entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Reference;
import org.springframework.data.annotation.Transient;

import java.util.ArrayList;

@Entity(name="Role")
public class Role implements Comparable<Role>
{
    //variables

    @Id
    private Long id;

    private String role;
    private String description;

    @Reference
    private ArrayList<Privilege> privileges;

    //booleans for form validation
    @Transient
    private boolean roleFormError;

    @Transient
    private boolean roleEmptyError;

    @Transient
    private boolean descEmptyError;

    @Transient
    private boolean privEmptyError;

    public Role(){}

    public Role(String role, String description, ArrayList<Privilege> privileges)
    {
        this.role = role;
        this.description = description;
        this.privileges = privileges;

    }

The Repository:

package ps_test_tool_datastore.repos.user_repos;

import org.springframework.cloud.gcp.data.datastore.repository.DatastoreRepository;
import ps_test_tool_datastore.repos.pojos.user_info.Role;


public interface RoleRepository extends DatastoreRepository<Role, Long>
{
    Role findByRole(String role);

    Role findByDescription(String description);

}

And the service:

package ps_test_tool_datastore.services.user_services;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ps_test_tool_datastore.repos.user_repos.PrivilegeRepository;
import ps_test_tool_datastore.repos.user_repos.RoleRepository;
import ps_test_tool_datastore.repos.pojos.user_info.Privilege;
import ps_test_tool_datastore.repos.pojos.user_info.Role;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Service
public class RoleServices //TODO: update template: implements RoleServiceTemplate 
{
    private RoleRepository roleDAOImplementation;

    private PrivilegeRepository privilegeDAOImplementation;

    public RoleServices(RoleRepository roleDAOImplementation, PrivilegeRepository privilegeDAOImplementation)
    {
        this.roleDAOImplementation = roleDAOImplementation;
        this.privilegeDAOImplementation = privilegeDAOImplementation;
    }

    final Logger logger = LoggerFactory.getLogger(RoleServices.class);



    //@Override
    public Role createRole(Role role) {

        //does a role with this name exist
        try
        {
            Role tempRole = roleDAOImplementation.findByRole(role.getRole());
            if (tempRole!=null)
            {
                logger.debug("Role with name {} already exists", role.getRole());
                return role;
            }
        }

        catch (Exception e)
        {
            logger.debug("Role with name {} not found", role.getRole());
        }

        //persist the Role to the database
        try{
            roleDAOImplementation.save(role);
            logger.debug("Role with ID " + role.getId() + " created");
        }

        catch (Exception e){
            logger.error("Unexpected Error creating Role");
            logger.error(e.getMessage(), e);
        }

        return role;
    }

    //@Override
    public Role getRoleByID(Long id) {


        try{

            Role roleResult = roleDAOImplementation.findById(id).get();
            logger.info("Role number {} returned successfully", roleResult.getId());

            return roleResult;

        }


        catch (Exception e){
            logger.error("Unexpected Error finding Role");
            logger.error(e.getMessage(), e);

            return null;
        }


    }

    //@Override
    public boolean updateRole(Role role) {

        //try to persist rol;e to DB
        try{
            roleDAOImplementation.save(role);
            logger.info("Role with ID {} updated", role.getId());
            return true;
        }


        catch (Exception e){
            logger.error("Unexpected Error updating Role");
            logger.error(e.getMessage(), e);

            return false;
        }

    }

    //@Override
    public List<Role> getAllRoles() {

        List<Role> roleList = new ArrayList<>();

        try{
            Iterable<Role> roles = roleDAOImplementation.findAll();
            for (Role role: roles)
                roleList.add(role);
        }

        catch (Exception e){
            logger.error("Unexpected Error getting Roles");
            logger.error(e.getMessage(), e);
        }

        return roleList;
    }

    public List<Privilege> getRolePrivs(Role role){

        return role.getPrivileges();

    }

    public Role addRolePrivs(Collection<Privilege> privileges, Role role){


        ArrayList<Privilege> privilegeArrayList = new ArrayList<>();

        for (Privilege privilege: privileges)
            privilegeArrayList.add(privilege);

        role.setPrivileges(privilegeArrayList);

        try{
            roleDAOImplementation.save(role);
            logger.info("Privileges for Role with ID {} updated", role.getId());
        }


        catch(Exception e){
            logger.error("Unexpected Error updating Role");
            logger.error(e.getMessage(), e);
        }


        return role;
    }


    public Role getRoleByName(String role)
    {

        try
        {
            return roleDAOImplementation.findByRole(role);
        }

        catch (Exception e)
        {
            return null;
        }
    }
}

Is there something obvious I am missing?

Where is the implementation for RoleRepository interface? The error is pointing to that it hasn't found any Bean implementing this interface.

The reason for this issue is clearly indicated in the Spring error:

expected at least 1 bean which qualifies as autowire candidate for this dependency

As the bean trying to be picked up automatically by classpath scanning and it is defined correctly I would say that it may be defined in a package that is not scanned by Spring . It may be simply out of the Spring context. Do you have any configuration like this?

@Configuration
@ComponentScan("some.random.package")
public class ContextWithJavaConfig {
...
}

If this issue is not related with the location where are you scanning the Spring components, I would recommend you to offer Spring some basic implementation for this repository, also. Even though, I know theoretically is unnecessary, just give it a try.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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