NoSuchBeanDefinitionException:没有类型合格的bean(存储库)

时间:2018-07-12 11:17:25

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

我想在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>

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

2 个答案:

答案 0 :(得分:0)

您可以更新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>

答案 1 :(得分:0)

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

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

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

@Service
@Qualifier("profileService")