使用Hibernate不会触发MySQL的“ ON UPDATE CURRENT_TIMESTAMP”

时间:2019-11-07 10:37:45

标签: java mysql hibernate jpa

在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]

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

我曾经要么绕过这个问题

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

两种方法的问题在于,直到发送出去,我才拥有更新的值:

[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首先不触发更新是否正常?

有没有办法在同一笔交易中获取更新的值?

1 个答案:

答案 0 :(得分:3)

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

JPA不知道数据库中的值正在更改,因此始终重新读取保存的值会对性能造成不利影响。这就是为什么在新事务中获得正确值的原因,因为实际上是从数据库中获取数据的。在同一笔交易中,该值仍在内存中并假定为不变。