Java 如何使用较新的JPA时间戳字段升级数据库?

Java 如何使用较新的JPA时间戳字段升级数据库?,java,mysql,jpa,migration,database-migration,Java,Mysql,Jpa,Migration,Database Migration,我有一个SpringBoot应用程序,它使用JPA和Hibernate自动管理我的实体。当我创建这个应用程序时,我使用了一个旧版本的JPA,它不支持Java8DateTime API。然而,在没有太多关于JPA的知识的情况下,我在我的实体中使用了LocalDateTime,它成功了!不必知道底层的数据库结构真是太棒了 直到现在 我正在将JPA升级到一个支持LocalDateTime的版本,而JPA使用此字段的方式遇到了一个错误。它以前在MySQL数据库中将此对象保存为VARBINARY(tiny

我有一个SpringBoot应用程序,它使用JPA和Hibernate自动管理我的实体。当我创建这个应用程序时,我使用了一个旧版本的JPA,它不支持Java8DateTime API。然而,在没有太多关于JPA的知识的情况下,我在我的实体中使用了
LocalDateTime
,它成功了!不必知道底层的数据库结构真是太棒了

直到现在

我正在将JPA升级到一个支持
LocalDateTime
的版本,而JPA使用此字段的方式遇到了一个错误。它以前在MySQL数据库中将此对象保存为
VARBINARY
(tinyblob)字段,但现在它很智能,希望它是
时间戳
类型。这意味着,当我使用配置
spring.jpa.hibernate.ddl auto=validate
启动我的应用程序时,我得到了错误:

...
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: 
    Schema-validation: wrong column type encountered in column [answer_time] in table [user_answer]; 
    found [tinyblob (Types#VARBINARY)], but expecting [datetime (Types#TIMESTAMP)]
所以现在我对如何将这些字段转换为新的时间戳类型有点迷茫。我曾考虑使用FlyWay编写迁移脚本,但我不知道JPA如何将对象存储为blob。将
VARBINARY
字段打印为字符串时,如下所示:

,'sr
java.time.Ser]º“H²xpwã
!;:;Ö@x

这是我的实体的外观(在升级过程中保持不变):

如何更新数据库,使其将用于存储
LocalDateTime
数据的旧
VARBINARY
字段转换为
TIMESTAMP
字段?

我将尝试什么(备份数据库后!):

  • 保留旧的JPAAPI+实现(Hibernate)版本
  • 保留旧的
    LocalDateTime
    字段
  • 将另一个
    java.sql.Date
    字段添加到实体中。确保正确地对其进行注释等,以便Hibernate准确地知道应该如何定义列
  • 对于所有实体:
    • 加载每个实体,读取
      LocalDateTime
      ,将其转换并存储到
      DateTime
      字段,
      merge()
  • 删除
    DateTime
    字段
  • 从表中删除旧的
    LocalDateTime
  • DateTime
    字段的类型更改为
    LocalDateTime
  • 升级JPAAPI+实现(Hibernate)版本

  • JPA impl(Hibernate?)应该将
    DateTime
    存储为
    TIMESTAMP
  • JDBC驱动程序应该能够将时间戳提取到
    LocalDateTime

也可以考虑<代码> ZONDATEDATIMECT/<代码>而不是<代码> LoalDATECTIMEON//> > .>代码> java .sql .DATEIME//C>不存在,我想你是说“java .sql .日期”或“代码> java . SQL .时间戳 .我想我理解你要解释的方法,所以我正在尝试.谢谢.也许.我的脑子里没有JavaDoc)但是谢谢你的注意,我把帖子修好了。

@Entity
@Table(name = "user_answer")
public class UserAnswer {
    private Long id;
    private LocalDateTime answerTime;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public LocalDateTime getAnswerTime() {
        return answerTime;
    }

    public void setAnswerTime(LocalDateTime answerTime) {
        this.answerTime = answerTime;
    }
}