Java 如何使用较新的JPA时间戳字段升级数据库?
我有一个SpringBoot应用程序,它使用JPA和Hibernate自动管理我的实体。当我创建这个应用程序时,我使用了一个旧版本的JPA,它不支持Java8DateTime API。然而,在没有太多关于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
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
- 将另一个
字段添加到实体中。确保正确地对其进行注释等,以便Hibernate准确地知道应该如何定义列java.sql.Date
- 对于所有实体:
- 加载每个实体,读取
,将其转换并存储到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;
}
}