Spring - 未创建CrudRepository

时间:2018-02-02 09:34:45

标签: java spring spring-mvc spring-data-jpa h2

CrudRepository bean

@Repository
public interface UserDao extends CrudRepository<User, Long>
{
    List<User> findByFirstNameAndLastName(String firstName, String lastName);
} 

用于User资源

@Entity
@Table(name="User")
public class User 
{
    @Id
    @GeneratedValue
    private long id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    /* --- Getters,setters,default constructor -------*/
}
我启动Spring启动应用程序时未创建

Field dao in base.package.service.UserService required a bean 
of type 'base.package.dao.UserDao' that could not be found.

但是包裹肯定是扫描的

@SpringBootApplication(scanBasePackages= {"base.package"})

我强烈怀疑它必须对我正在使用的嵌入式数据库h2做些什么。我正在尝试在User

中创建schema.sql
CREATE TABLE IF NOT EXISTS User (
    id   INTEGER      NOT NULL AUTO_INCREMENT,
    first_name VARCHAR(128) NOT NULL,
    last_name VARCHAR(128) NOT NULL,
    PRIMARY KEY (id)
);

但是一旦我取消注释IF NOT EXISTS它就会抛出错误(表已经存在)。所以这首先意味着spring负责创建架构。但我感觉表格没有重新创建,因为在data.sql脚本

INSERT INTO User (id,first_name,last_name) VALUES (1,'Vincent', 'Vega');

我总是必须在启动时手动增加id,否则我会得到

org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.USER(ID)"

以下是application.properties

的jpa属性
# below properties create schema, so schema.sql is redundant
spring.jpa.generate-ddl=true  
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.initialization-mode=always
spring.jpa.database=H2
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:~/testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE


spring.datasource.name=testdb
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

我认为该表永远不会在启动时重新创建的原因是因为我在应用关闭时收到此错误

2018-02-02 09:27:47.907 INFO  [restartedMain] [StandardService] Stopping service [Tomcat]
2018-02-02 09:27:47.907 WARN  [localhost-startStop-1] [WebappClassLoaderBase] The web application [ROOT] appears to have started a thread named [MVStore background writer nio:C:/Users/user/testdb.mv.db] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Object.wait(Native Method)

接下来是未创建UserDao bean的异常。

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

Description:

Field dao in base.package.user.service.UserService required a bean of type 'base.package.user.dao.UserDao' that could not be found.


Action:

Consider defining a bean of type 'base.package.user.dao.UserDao' in your configuration.

的pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.M7</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>
        <spring-cloud.version>Finchley.M5</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
       /* .... */

修改

以下是UserService

@Service
public class UserService 
{
    @Autowired private UserDao dao;

    public List<User> findByFirstNameAndLastName(String firstName, String lastName)
    {
        return dao.findByFirstNameAndLastName(firstName, lastName);
    }

    public User save(final User user)
    {
        return dao.save(user);
    }
}

编辑2

现在我要

Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.project.bot.user.User
    at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:472)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:72)
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:169)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:107)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:90)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:300)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$3(RepositoryFactoryBeanSupport.java:287)
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:141)
    at org.springframework.data.util.Lazy.get(Lazy.java:63)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:290)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:102)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706)
    ... 102 common frames omitted

1 个答案:

答案 0 :(得分:7)

未创建的表不应对bean是否已定义产生任何影响。

我认为你在这里遇到的问题是你没有实现你的存储库bean。 Spring Data JPA存储库bean不会被组件扫描拾取,因为它们只是接口。 @Repository注释在这里实际上什么也没做。

Spring Data JPA repo bean是动态创建的,只要您在配置中提供了@EnableJpaRepositories

您可能还需要放置@EntityScan以确保所有@ Entity都被Spring识别

@SpringBootApplication(scanBasePackages= {"base.package"})
@EnableJpaRepositories("base.package")
@EntityScan("base.package")