【问题标题】:JPA entity update via "getById & save" didn't updated it's updatedtimestamp column通过“getById & save”更新 JPA 实体没有更新它的更新时间戳列
【发布时间】:2021-11-03 06:39:41
【问题描述】:

我现在正在尝试使用“getById & save”来更新实体的列,如下所示。

// update "title" column 
val entityRef = entityRepository.getById(entityID)
entityRef.title = futureTitle 
return entityRepository.save(entityRef)

但是,如果我运行代码,即使该列已完美更新,updatedtimestamp 列(描述为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)也不会改变。

似乎updatedtimestamp 列仅在我使用自定义“UPDATE”查询时才会更新。

    @Modifying
    @Transactional
    @Query("update Entity p set p.title = :newTitle where p.id = :entityId")
    fun updateEntityTitle(entityId: Long, newTitle: String)

我能知道为什么通过“getById & save”更新实体没有改变updatedtimestamp吗?

提前致谢!

【问题讨论】:

    标签: mysql jpa spring-data-jpa


    【解决方案1】:

    ON UPDATE CURRENT_TIMESTAMP 是 MySql 的 SQL 方言的构造。描述如下in the documentation

    当行中任何其他列的值从其当前值更改时,自动更新的列会自动更新为当前时间戳。如果所有其他列都设置为其当前值,则自动更新的列保持不变。要防止自动更新的列在其他列更改时更新,请将其显式设置为其当前值。要在其他列未更改的情况下更新自动更新的列,请将其显式设置为应具有的值(例如,将其设置为 CURRENT_TIMESTAMP)。

    由于所有 JPA 实现都会更新所有列,无论它们是否更改,它们也会为您的 CURRENT_TIMESTAMP 列提供一个值,从而防止文档中描述的任何自动更新。

    您有多种方法可以使用此技术堆栈获取更新时间戳:

    1. 您可以使用动态插入来仅更新已更改的字段。请注意,在大多数情况下,这对性能不利。见Hibernate: Dirty Checking and Only Update of Dirty Attributes?

    2. 您可以使用@Column(updatable=false) 将列设为只读。见JPA readonly mapping

    3. 您可以使用Hibernates UpdateTimestamp for this purpose,而不是使用MySql 功能

    4. 或者你使用JPAs EntityListener

    5. 而且由于您似乎使用 Spring Data JPA,您也可以使用 Spring Datas @LastModifiedDate

    【讨论】:

    • 因为@LastModifiedDate 不适用于我的情况,(似乎我必须为我的配置类启用 EnableJpaAuditing 才能使用它)所以我使用了@Column(updatable=false),现在它可以工作了:) 谢谢你这么多!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 2010-12-17
    • 1970-01-01
    • 2019-02-09
    相关资源
    最近更新 更多