【问题标题】:NoSuchBeanDefinitionException: No qualifying bean of type (repository)NoSuchBeanDefinitionException:没有符合条件的 bean 类型(存储库)
【发布时间】:2018-12-20 14:29:09
【问题描述】:

我想测试在 Spring Boot 中实现的简单应用程序中创建配置文件。我决定使用 Postman 以 JSON 格式发送适当的 POST:

{
    "id": "Fred41",
    "nick": "Fred",
    "password": "Flintstone",
    "email": "fredflintstone@yahoo.com",
    "wonPenalties": 2,
    "lostPenalties": 1,
    "wonMatches": 2,
    "lostMatches": 3
}

但是,发送后的结果如下(反正和IntelliJ IDEA的控制台一样):

{
    "timestamp": "2018-07-12T11:07:19.434+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "No qualifying bean of type 'io.github.plkpiotr.fifabackend.repository.ProfileRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}",
    "path": "/register"
}

即:没有可用的 (...) 类型的合格 bean:预计至少有 1 个 bean 有资格作为自动装配候选者。依赖注释:{}

Profile.java:

@Entity
@Table(name = "profiles")
@Data
@Builder(builderMethodName = "setIdForNewProfile")
public class Profile {
    @Id
    private String id;

    @NotNull
    @Size(min = 3, max = 25)
    @Pattern(regexp = "^[a-zA-Z]+(([',. -][a-zA-Z ])?[a-zA-Z]*)*$")
    private String nick;

    @NotNull
    @Size(min = 6, max = 15)
    private String password;

    @NotNull
    @Email
    private String email;

    @NotNull
    private long wonPenalties;

    @NotNull
    private long lostPenalties;

    @NotNull
    private long wonMatches;

    @NotNull
    private long lostMatches;

    public static ProfileBuilder builder() {
        return setIdForNewProfile()
                .id(UUID.randomUUID().toString());
    }
}

ProfileDTO.java:

@Data
@Builder
public class ProfileDTO {
    private String id;
    private String nick;
    private String password;
    private String email;
    private long wonPenalties;
    private long lostPenalties;
    private long wonMatches;
    private long lostMatches;
}

ProfileRepository.java:

@Repository
public interface ProfileRepository extends JpaRepository<Profile, String> {

    Optional<Profile> findById(String id);

    Optional<Profile> findByNick(String nick);

    List<Profile> findAllByOrderByWonMatchesAsc();

    List<Profile> findAllByOrderByWonPenalties();

    void delete(String id);
}

ProfileService.java:

@Service
public class ProfileService {
    private final ProfileRepository profileRepository;

    @Lazy
    @Autowired
    public ProfileService(ProfileRepository profileRepository) {
        this.profileRepository = profileRepository;
    }

    private ProfileDTO mapToDTO(Profile profile) {
        return ProfileDTO.builder()
                .id(profile.getId())
                .nick(profile.getNick())
                .password(profile.getPassword())
                .email(profile.getEmail())
                .build();
    }

    public ProfileDTO createProfile(ProfileDTO profileDTO) {
        Profile profile = Profile.builder()
                .nick(profileDTO.getNick())
                .password(profileDTO.getPassword())
                .email(profileDTO.getEmail())
                .build();

        profileRepository.save(profile);
        return mapToDTO(profile);
    }

    public List<ProfileDTO> readAllProfiles() {
        return profileRepository.findAll()
                .stream()
                .map(this::mapToDTO)
                .collect(Collectors.toList());
    }

    public Optional<ProfileDTO> readWorkerByEmail(String email) {
        return Optional.of(mapToDTO(Objects.requireNonNull(profileRepository.findByNick(email).orElse(null))));
    }

    public ProfileDTO updateProfile(ProfileDTO profileDTO) {
        Profile profile = profileRepository.findById(profileDTO.getId()).orElse(null);
        Objects.requireNonNull(profile).setNick(profileDTO.getNick());
        profileRepository.save(profile);
        return mapToDTO(profile);
    }

    public void deleteProfile(String id) {
        profileRepository.delete(id);
    }
}

ProfileController.java:

@RestController
public class ProfileController {
    private final ProfileService profileService;

    @Autowired
    public ProfileController(ProfileService profileService) {
        this.profileService = profileService;
    }

    @PostMapping(value= "/register", consumes = APPLICATION_JSON_VALUE)
    public ResponseEntity<ProfileDTO> createProfile(ProfileDTO profileDTO) {
        profileService.createProfile(profileDTO);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }
}

和FifaBackendApplication.java:

@SpringBootApplication
@ComponentScan("io.github.plkpiotr.fifabackend")
public class FifaBackendApplication {

    public static void main(String[] args) {
        SpringApplication.run(FifaBackendApplication.class, args);
    }
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>io.github.plkpiotr</groupId>
    <artifactId>fifa-backend</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>fifa-backend</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-security</artifactId>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>3.6.1</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.10.Final</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

你能解释一下我做错了什么吗? 毕竟我使用与以前的项目类似的注释......

【问题讨论】:

    标签: java json rest spring-mvc spring-boot


    【解决方案1】:

    您可以更新 FifaBackendApplication 以显式定义 Bean 包,例如 EnableJpaRepositoriesEntityScan 注释。

    @SpringBootApplication
    @ComponentScan("io.github.plkpiotr.fifabackend")
    @EntityScan(basePackages = {"EntityPackage"} )
    @EnableJpaRepositories(basePackages = {"RepositoryPackage"})
    public class FifaBackendApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(FifaBackendApplication.class, args);
        }
    
    }
    

    更新 - 修改 pom.xml 以排除 hibernate-corehibernate-enitity 经理和

     <dependency>
        <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
             <exclusions>
             <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

    【讨论】:

    • 感谢您的回复,但我之前试过这个,我在构建应用程序时得到:Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: At least one JPA metamodel must be present!
    • 你能提供你的 pom.xml 吗?
    • 能否排除Spring Boot的Hibernate依赖` org.springframework.bootspring-boot-starter-data-jpaorg.hibernatehibernate-entitymanagerorg.hibernatehibernate-core `
    • 我没有连接数据库,但我不相信这就是原因。
    【解决方案2】:

    @Service 添加限定符名称,如下所示:

    @Service("profileService") 应该可以解决您的问题

    或在@Service 之后添加@Qualifier 注释,如下所示:

    @Service
    @Qualifier("profileService")
    

    【讨论】:

    • 谢谢,还是一样。
    • 不幸的是,是的。也许我真的什么都没看到。我的仓库在这里:github.com/plkpiotr/fifa-backend
    • 在github代码Repository注解被注释了..能查一次吗?
    • 因为我没有推送不工作的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 2017-11-27
    • 2020-06-18
    • 2020-06-10
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多