Spring - 没有创建CrudRepository

ten*_*con 3 java spring spring-mvc h2 spring-data-jpa

CrudRepository

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

对于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 -------*/
}
Run Code Online (Sandbox Code Playgroud)

我启动Spring启动应用程序时不会创建

Field dao in base.package.service.UserService required a bean 
of type 'base.package.dao.UserDao' that could not be found.
Run Code Online (Sandbox Code Playgroud)

但包裹肯定是扫描的

@SpringBootApplication(scanBasePackages= {"base.package"})
Run Code Online (Sandbox Code Playgroud)

我强烈怀疑它必须对h2我正在使用的嵌入式数据库做些什么.我正在尝试创建Userschema.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)
);
Run Code Online (Sandbox Code Playgroud)

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

INSERT INTO User (id,first_name,last_name) VALUES (1,'Vincent', 'Vega');
Run Code Online (Sandbox Code Playgroud)

我总是必须手动增加id启动,否则我得到一个

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

以下是jpa属性 application.properties

# 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
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

接下来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.
Run Code Online (Sandbox Code Playgroud)

的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>
       /* .... */
Run Code Online (Sandbox Code Playgroud)

编辑

这里是 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑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
Run Code Online (Sandbox Code Playgroud)

Plo*_*log 8

未创建的表不应对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")
Run Code Online (Sandbox Code Playgroud)

  • 不,因为 Spring 数据存储库是特殊的。它们只是接口,因此不能定义为 `@Components`。Spring data 根据您定义的存储库动态创建具体实现。但是如果你有`@EnableJpaRepositories` 注释,它只会制作这些具体的bean (2认同)