gradle 从内存数据库转换为spring-data-jpa时,“No qualifying bean of type 'com.genecab.bank.AccountRepository' available”

qyzbxkaa  于 12个月前  发布在  Spring
关注(0)|答案(1)|浏览(217)

第一次在应用程序中使用JPA持久化H2数据库时,我几乎已经完成了,但我遇到了错误消息No qualifying bean of type 'com.genecab.bank.AccountRepository' available。应用程序在内存中工作,但当spring-data-jpa添加到build.gradle时,它找不到此bean。
我运行的命令如下:

java -jar -Dspring.profiles.active=local build\libs\bank-0.0.1-SNAPSHOT.jar

字符串
以下是Spring日志中有关失败的更多详细信息:

2023-12-02T09:37:16.805-05:00  INFO 24540 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1944 ms
2023-12-02T09:37:16.848-05:00  INFO 24540 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2023-12-02T09:37:17.173-05:00  INFO 24540 --- [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:file:C:/data/bank user=BANK-USER
2023-12-02T09:37:17.178-05:00  INFO 24540 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2023-12-02T09:37:17.197-05:00  INFO 24540 --- [           main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2'. Database available at 'jdbc:h2:file:C:/data/bank'
2023-12-02T09:37:17.400-05:00  INFO 24540 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 9.5.1 by Redgate
2023-12-02T09:37:17.401-05:00  INFO 24540 --- [           main] o.f.c.internal.license.VersionPrinter    : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#9.5.1
2023-12-02T09:37:17.408-05:00  INFO 24540 --- [           main] o.f.c.internal.license.VersionPrinter    :
2023-12-02T09:37:17.431-05:00  INFO 24540 --- [           main] o.f.c.i.database.base.BaseDatabaseType   : Database: jdbc:h2:file:C:/data/bank (H2 2.1)
2023-12-02T09:37:17.514-05:00  INFO 24540 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 1 migration (execution time 00:00.024s)
2023-12-02T09:37:17.526-05:00  INFO 24540 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "PUBLIC": 2
2023-12-02T09:37:17.528-05:00  INFO 24540 --- [           main] o.f.core.internal.command.DbMigrate      : Schema "PUBLIC" is up to date. No migration necessary.
2023-12-02T09:37:17.664-05:00  INFO 24540 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2023-12-02T09:37:17.757-05:00  INFO 24540 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.1.7.Final
2023-12-02T09:37:18.269-05:00  INFO 24540 --- [           main] SQL dialect                              : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2023-12-02T09:37:18.672-05:00  INFO 24540 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2023-12-02T09:37:18.690-05:00  INFO 24540 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2023-12-02T09:37:18.708-05:00  WARN 24540 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountController' defined in URL [jar:file:/C:/Users/biz/IdeaProjects/genecab-bank/build/libs/bank-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/genecab/bank/AccountController.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'com.genecab.bank.AccountRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2023-12-02T09:37:18.708-05:00  INFO 24540 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2023-12-02T09:37:18.719-05:00  INFO 24540 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2023-12-02T09:37:18.762-05:00  INFO 24540 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2023-12-02T09:37:18.766-05:00  INFO 24540 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-12-02T09:37:18.788-05:00  INFO 24540 --- [           main] .s.b.a.l.ConditionEvaluationReportLogger :

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-12-02T09:37:18.819-05:00 ERROR 24540 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

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

Description:

Parameter 0 of constructor in com.genecab.bank.AccountController required a bean of type 'com.genecab.bank.AccountRepository' that could not be found.

Action:

Consider defining a bean of type 'com.genecab.bank.AccountRepository' in your configuration.


这是我的版本。gradle:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.5'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.genecab'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.data:spring-data-jdbc'
    implementation 'com.h2database:h2'
    implementation 'org.flywaydb:flyway-core'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}


当我注解掉spring-boot-starter-data-jpa行时,我的单元测试通过了:

// implementation 'org.springframework.boot:spring-boot-starter-data-jpa'


..

BankApplicationTests > shouldCreateANewJournalEntry() FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:142
        Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:798
            Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException at DefaultListableBeanFactory.java:1824


因此,它似乎类似于原始日志中的问题,当试图运行bootRun与本地配置。
以下是我的application-local.properties:

spring.datasource.url=jdbc:h2:file:C:/data/bank
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=bank-user
spring.datasource.password=&zsD9*PfZ0sgfNbW
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.flyway.user=bank-user
spring.flyway.password=&zsD9*PfZ0sgfNbW
spring.flyway.url=jdbc:h2:file:C:/data/bank
spring.flyway.locations=classpath:db/migration
spring.flyway.enabled=true

# H2
spring.h2.console.enabled=true
spring.h2.console.path=/h2


我的AccountRepository.java:

package com.genecab.bank;

import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface AccountRepository extends CrudRepository<Account, Long>, PagingAndSortingRepository<Account, Long> {
    Account findByIdAndOwner(Long id, String owner);
    Page<Account> findByOwner(String owner, PageRequest amount);

    Optional<Account> findById(Long accountId);
}


完整的源代码可以在this Github source code link上找到,如果这样做更容易的话。
我也尝试添加@EnableJpaRepositories,但这不起作用。
我花了一段时间进行模式初始化,最终实现了flyway,它在日志中显示模式初始化成功,因此我知道正在创建底层表和数据。

ccgok5k5

ccgok5k51#

首先,您将记录用作JPA的实体

public record Account(@Id Long id, String name, String type, String owner {

}

字符串
实体由JPA提供程序处理。JPA提供程序负责创建数据库表,将实体Map到表,并将实体持久化到数据库。在流行的JPA提供程序(如Hibernate)中,使用代理创建和管理实体。
代理是在运行时生成并扩展实体类的类。这些代理依赖于实体类具有无参数构造函数和setter。由于记录没有这些,它们不能用作实体。
现在,您可以执行以下操作,请记住@Table是可选的

@Entity 
@Table(name = "account")
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String type;
    private String owner;

    // JPA requires a no argument constructor
    protected Account() {}

    public Account(Long id, String name, String type, String owner) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.owner = owner;
    }

    // Getters and setters (if not using Lombok)
    // ...
}


根据您共享的代码,BankApplication和AccountRepository位于同一个包(com.genecab.bank)中,组件扫描应该自动将AccountRepository作为Spring Bean。

@EnableJpaRepositories(basePackages = "com.genecab.bank")


我也建议你去掉不必要的依赖

implementation 'org.springframework.data:spring-data-jdbc'

相关问题