java - 使用Hibernate不会触发MySQL的 "ON UPDATE CURRENT_TIMESTAMP"

标签 java mysql hibernate jpa

在 MySQL 数据库中,每个表都有一个列 updated,其创建方式为

[...] `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

正如预期的那样,每行更新都会触发时间戳更新到 CURRENT_TIMESTAMP。当我通过 SQL shell、命令行、DBeaver、Workbench 更新一行时,情况确实如此但是

使用 Hibernate(Spring Boot 2、Spring Data JPA)不起作用。我的意思是,伪代码例如:

[Tx]
entity = repository.findById(1) --> Returns my entity with updated == 1L 
entity.setProperty("other value")
repository.save(entity)
[/Tx]

此时,数据库条目已更新(“其他值”是当前值),但已更新列仍为 1L,其中应为 CURRENT_TIMESTAMP

我曾经绕过这个问题

  • 将属性注释为@UpdateTimestamp或 h
  • 使用 @PrePersist && @PreUpdate 注释一个方法,该方法会在 UPDATE SQL 语句之前以编程方式设置当前时间戳

这两种方法的问题是,直到我的 Tx 之外我都没有更新的值:

[Tx]
entity.getUpdated() == 1L
entity.setName("other")
repository.save(entity) // at this point the updated is still == 1L
repository.findById()  // at this point the updated is still == 1L
[/Tx]

[Tx]
repository.findById()  // good timestamp value
[Tx]

MySQL 一开始不触发更新,这正常吗?

有没有办法在同一事务中获取更新后的值?

最佳答案

您需要JPARepository.saveAndFlush() (或使用原始 JPA,EntityManager.refresh())在同一事务中从数据库获取更新的值。这会影响所有数据库生成的值。

JPA 不知道数据库内部的值正在发生变化,并且总是重新读取保存的值会对性能产生不利影响。这就是为什么在新事务中您会获得正确的值,因为数据实际上是从数据库中获取的。在同一笔交易中,该值仍在内存中,并假定未更改。

关于java - 使用Hibernate不会触发MySQL的 "ON UPDATE CURRENT_TIMESTAMP",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58746891/

相关文章:

mysql - 内连接如何嵌套?

java - JPA/Hibernate "simple"OneToMany 单向/清除集不起作用

mysql - 在MYSQL查询中设置位置参数

java - 将未实现的接口(interface)转换为对象

java - 多个广播使用 AlarmManager 和 BroadcastReceiver 调用自己

java - 是否可以在运行时指定上下文属性占位符

java - 正则表达式:删除第二个 "-"之前和之后的所有内容

mysql - 在mysql查询中重新输入别名列

MySQL 服务器已消失(代码 2006)

java - 使用 ejb3/hibernate 运行查询时出现奇怪的错误