SpringBoot,Hibernate和Flyway数据库问题

时间:2018-09-27 18:55:55

标签: java hibernate spring-boot h2 flyway

使用rieckpil建议进行了更新

嗨,

现在我正面临一个仅在使用CrudRepository从H2 DB中添加/读取实体时出现的问题。

一个非常基本的示例,可以工作:

我的属性

spring.datasource.url=jdbc:h2:file:~/flyawayTest;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE
spring.datasource.username=admin
spring.datasource.password=password
spring.datasource.driver-class-name=org.h2.Driver
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.flyway.baseline-on-migrate = true

和一个示例类

@Entity
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String username;

    public User() {
    }

    public User(String username) {
        this.username = username;
    }

    public User(String username, long lastLogin) {
        this.username = username;
        //this.lastLogin = lastLogin;
    }
}

使用此 .sql文件

CREATE TABLE USER (
  ID bigint(20) NOT NULL AUTO_INCREMENT,
  USERNAME varchar(100) NOT NULL,
  PRIMARY KEY (ID)
);

insert into USER (USERNAME) values ('User');

ALTER TABLE USER ADD COLUMN LASTLOGIN bigint(20) default 0

如果我要使用CrudRepository,我会得到例外

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing column [last_login] in table [user]

回购

@Repository
public interface UserRepo extends CrudRepository<User, Long> {

}

助手类以测试此过程

@Component
public class UCML implements CommandLineRunner {


    private final UserRepo userRepo;

    public UCML(UserRepo userRepo) {
        this.userRepo = userRepo;
    }

    @Override
    public void run(String... args) throws Exception {

        userRepo.save(new User("TestUser"));
        userRepo.findAll().forEach(System.out::println);
    }
}

V1__baseline.sql (为空,因为它仅用于获取包含用户TestUser的数据库的基线

V2__migrate.sql

ALTER TABLE USER ADD COLUMN LASTLOGIN bigint(20) default 0

我的步骤是:

  1. 向我的空数据库添加新用户userRepo.save(new User("A"));
  2. 关机应用程序
  3. 将flywaydb依赖项添加到我的pom中
  4. 创建一个名为V1__baseline.sql的空.sql文件以使用spring.flyway.baseline-on-migrate = true并启动应用程序,成功然后关闭
  5. 创建一个名为V2__migrate.sql的新sql文件,其内容为ALTER TABLE USER ADD COLUMN LASTLOGIN bigint(20) default 0

然后将字段private long lastLogin;添加到类User中。

当我现在再次启动该应用程序时,我收到上面提到的错误

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing column [last_login] in table [user]

那么我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

您的类字段名为lastLogin,然后Hibernate将其转换为last_login,以在数据库中找到一列。您必须像这样手动指定字段对应的列:

@Data
@Entity
@Table(name = "USER", schema = "YOUR_SCHEMA_NAME")
public class User {

    @Id
    @Column(name = "ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Basic
    @Column(name = "USERNAME", nullable = false)
    private String username;

    @Basic
    @Column(name = "LASTLOGIN")
    private Long lastLogin = 0;
}

此外,您不再需要@Repository

您必须使用SpringBootServletInitializer批注标记@EnableJpaRepositories类,以指示CrudRepository所在的软件包。

答案 1 :(得分:0)

您的Flyway脚本似乎没有填充。您必须遵循V01__INIT.sql之类的Flyway命名约定(您需要两个_)并将它们存储在src/main/resources/db/migration中。

在应用程序启动期间,您应该看到Flyway填充了您的脚本或已将最新架构应用于数据库的日志。

您可以在此处找到一个简单的Flyway示例:https://flywaydb.org/getstarted/how

此外,我建议使用spring.jpa.hibernate.ddl-auto=validate以确保只有Flyway创建您的数据库架构。