【问题标题】:Using Hibernate doesn't trigger MySQL's "ON UPDATE CURRENT_TIMESTAMP"使用 Hibernate 不会触发 MySQL 的“ON UPDATE CURRENT_TIMESTAMP”
【发布时间】:2020-03-03 22:12:32
【问题描述】:

在 MySQL 数据库中,每个表都有一个列 updated,它被创建为

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

正如预期的那样,每次行更新都会触发时间戳对 CURRENT_TIMESTAMP 的更新。当我通过 SQL shell、命令行、DBeaver、Workbench BUT

更新一行时,这是真的

使用 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]

此时,DB 条目已更新(“其他值”为当前值)但updated 列仍为 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一开始不触发更新正常吗?

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

【问题讨论】:

  • 您能否运行SHOW CREATE TABLE yourTable 并检查此时间戳列是否实际上具有ON UPDATE 子句?我怀疑它可能不会。
  • 是的,确实如此。如问题中所述,当使用命令行或 DBeaver 等 SQL IDE 时,会发生更新。只有在通过 JPA 时这不起作用(可能是其他框架,但我不能确定)

标签: java mysql hibernate jpa


【解决方案1】:

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

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

【讨论】:

  • 好吧,只要我通过注释手动进行更新(@Prepersist @PreUpdate 或 @UpdatedTimestamp),这实际上就可以工作
  • @luso 这些不是数据库生成的值。它们是在 Java 端生成的。我解释了为什么在同一个事务中看不到数据库生成的值。
  • 是的,我明白了。实际上,除非我 saveAndFlush(),否则生成的 DB(更新 CURRENT_TIMESTAMP)或生成的 Hibernate(注释)都会更新。现在可以了,谢谢!但是,如果我摆脱注释,MySQL 触发器仍然不会触发。但后来我认为是因为 Hibernate 将查询中的“更新”字段添加到当前值,即使它没有改变,这会阻止 MySQL 覆盖它。
  • @luso 啊是的,你需要调整@Columninsertableupdatable 参数,如果这些还不够的话,可能在列上使用Hibernate 的@Generated。跨度>
猜你喜欢
  • 2011-07-31
  • 2014-02-11
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 2011-09-29
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多