关于更新 CURRENT_TIMESTAMP 和 JPA

发布于 2024-11-18 15:02:09 字数 752 浏览 3 评论 0原文

我有一个带有字段的实体

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "edit_timestamp", 
        columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private Date editTimestamp;

@Version
@Column(name = "edit_count")
private short editCount;

private String text;

当我尝试使用 Spring-Data-JPA 进行更新时,我观察 edit_count 已增加,但 edit_timestamp 仍然保持不变。如果我手动调用 SQL,

UPDATE post SET TEXT='456' WHERE post_id=1;

edit_timestamp 就会更新。如果我添加

@PreUpdate
protected void onUpdate() {
    editTimestamp = new Date();
}

它,它就不会出现问题。我的问题是为什么没有 @PreUpdate edit_timestamp 没有更新?

I have an entity with fields

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "edit_timestamp", 
        columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private Date editTimestamp;

@Version
@Column(name = "edit_count")
private short editCount;

private String text;

When I try to update with Spring-Data-JPA, I observe edit_count has been incremented, but edit_timestamp still remain the same. If I manually invoke SQL

UPDATE post SET TEXT='456' WHERE post_id=1;

the edit_timestamp is updated. If I add

@PreUpdate
protected void onUpdate() {
    editTimestamp = new Date();
}

it works w/o issue. My question is why w/o @PreUpdate the edit_timestamp is not updated?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

醉南桥 2024-11-25 15:02:09

您需要更改列注释以包含 updateable = false。这将导致 edit_timestamp 列不会显示在更新 SQL 中,因此 JPA 提供程序不会包含该字段的当前值,这正是导致其覆盖默认值的原因。

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "edit_timestamp", 
        updatable = false,
        columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private Date editTimestamp;

You need to change the column annotation to include updatable = false. This will cause the edit_timestamp column to not show up in the update SQL, so the JPA provider won't include the current value of the field which is what is causing it to override the default.

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "edit_timestamp", 
        updatable = false,
        columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private Date editTimestamp;
感情旳空白 2024-11-25 15:02:09

您可以将变量标记为实体中的更新或创建时间戳。在下面的示例中,您可以看到如何使用 hibernate 注释非常轻松地完成此操作:

@UpdateTimestamp
private LocalDateTime editTimestamp;

@CreationTimestamp
private LocalDateTime creationTimestamp;

仅供参考并确保不会造成混淆,我对相应的数据类型和注释使用以下包导入:

import org.hibernate.annotations.CreationTimestamp
import org.hibernate.annotations.UpdateTimestamp
import java.time.LocalDateTime

You can mark the variables as update or creation timestamps in your entity. In the following example you can see how this can be done very easily using hibernate annotations:

@UpdateTimestamp
private LocalDateTime editTimestamp;

@CreationTimestamp
private LocalDateTime creationTimestamp;

Just for the reference and to make sure there is no confusion, I am using the following package imports for the respective datatypes and annotations:

import org.hibernate.annotations.CreationTimestamp
import org.hibernate.annotations.UpdateTimestamp
import java.time.LocalDateTime
毁梦 2024-11-25 15:02:09

这里“created_date”字段默认在mysql中设置,默认/表达式是“CURRENT_TIMESTAMP”在此处查看图像文件。

在您的实体类中,如下所示-

      private Date updated_date;

      @PrePersist
      @PreUpdate
      protected void onUpdate() {
            updated_date = new Date();
      }

      @Temporal(TemporalType.TIMESTAMP)
      public Date getUpdated_date() {
           return updated_date;
      }

      public void setUpdated_date(Date updated_date) {
           this.updated_date = updated_date;
      }

here "created_date" fields by default set in mysql with default/expression is "CURRENT_TIMESTAMP" see image file here.
and
In your Entity Class like below-

      private Date updated_date;

      @PrePersist
      @PreUpdate
      protected void onUpdate() {
            updated_date = new Date();
      }

      @Temporal(TemporalType.TIMESTAMP)
      public Date getUpdated_date() {
           return updated_date;
      }

      public void setUpdated_date(Date updated_date) {
           this.updated_date = updated_date;
      }
小嗷兮 2024-11-25 15:02:09

因为在您最初的一组注释中,您所告诉它的有关 edit_timestamp 列的只是它是一个时间戳; JPA 不知道它需要更新它。我猜测当您手动执行 SQL 语句时,您有某种更新触发器正在为您更改这些字段 - 但在您更新它时会被来自持久实体的数据覆盖。
如果您不需要“已编辑”计数/时间戳,请尝试从实体中删除它们,然后看看是否有效。否则,你就有了一个可行的解决方案。

Because in your initial set of annotations, all you've told it about the edit_timestamp column is that it is a timestamp; JPA doesn't know that it needs to update it. I'm guessing that when you're manually executing the SQL statement, you have some sort of on-update trigger that's changing those fields for you - but are being overwritten by the data coming from the persisted entity when you update it.
If you don't need the 'edited' count/timestamp, try removing them from the entity, and see if that works. Otherwise, you have a working solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文