如何让 created_at 列自动生成创建日期时间,就像自动创建 ID 一样?
Posted
技术标签:
【中文标题】如何让 created_at 列自动生成创建日期时间,就像自动创建 ID 一样?【英文标题】:How can you make a created_at column generate the creation date-time automatically like an ID automatically gets created? 【发布时间】:2018-10-01 22:45:49 【问题描述】:我目前有一个实体如下:
@Entity
public class Product
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long productId;
private String productImage;
private String productTitle;
private String productDescription;
private Integer productPrice;
private Date createdAt;
private Date updatedAt;
创建此对象后,createdAt 和 updatedAt 的值在数据库中显示为 null,我想知道如何实现代码以便自动插入 createdAt 和 updateAt?
我的发帖方式如下:
@PostMapping("/products")
public ProductResponse createProduct(@Validated @RequestBody ProductForm productForm)
Product product = productForm.asProduct();
Product createdProduct = productRepository.save(product);
return new ProductResponse(createdProduct, "Product created");
【问题讨论】:
【参考方案1】:JPA
没有什么比直接注释 Timestamp 字段更方便的方法了,但您可以使用 @PrePersist
、@PreUpdate
注释并轻松获得相同的结果。
休眠
@CreationTimestamp
- Documentation
@UpdateTimestamp
- Documentation
Spring Data JPA
@CreatedDate
- Documentation
@LastModifiedDate
- Documentation
【讨论】:
这个是设置系统时间还是数据库系统时间?我的问题是有时系统时间可能是错误的并且无法控制它,而 db 系统的时间是正确的(更重要的是唯一的)【参考方案2】:在您的实体中扩展以下抽象类:
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class DateAudit implements Serializable
@CreatedDate
@Column(name = "created_at", nullable = false, updatable = false)
private Date createdAt;
@LastModifiedDate
@Column(name = "updated_at")
private LocalDateTime updatedAt;
不要忘记使用 @EnableJpaAuditing
启用 JPA 审计功能
阅读:https://docs.spring.io/spring-data/jpa/docs/1.7.0.DATAJPA-580-SNAPSHOT/reference/html/auditing.html
【讨论】:
一个更好、更有效的解决方案,直截了当。赞赏!!【参考方案3】:您可以创建一个 BaseEntity。每个实体都扩展了 BaseEntity。在 Base 实体中,它会自动设置时间
@Data
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity implements Serializable
@Id
@Column(name = "Id")
private String id;
@Column(name = "deleted", columnDefinition = "Bit(1) default false")
private boolean deleted = false;
@Column(name = "DataChange_CreatedBy", nullable = false)
private String dataChangeCreatedBy;
@Column(name = "DataChange_CreatedTime", nullable = false)
private Date dataChangeCreatedTime;
@Column(name = "DataChange_LastModifiedBy")
private String dataChangeLastModifiedBy;
@Column(name = "DataChange_LastTime")
private Date dataChangeLastModifiedTime;
@PrePersist
protected void prePersist()
if (this.dataChangeCreatedTime == null) dataChangeCreatedTime = new Date();
if (this.dataChangeLastModifiedTime == null) dataChangeLastModifiedTime = new Date();
@PreUpdate
protected void preUpdate()
this.dataChangeLastModifiedTime = new Date();
@PreRemove
protected void preRemove()
this.dataChangeLastModifiedTime = new Date();
【讨论】:
【参考方案4】:结合@dimitrisli 和@buddha 的答案,一些相当干净的东西是
@Data
@MappedSuperclass
public abstract class BaseEntity
@Column(updatable = false)
@CreationTimestamp
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
现在您的所有实体都可以像这样扩展该类
@Data
@Entity
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity
@Id
@GeneratedValue
public UUID id;
public String userName;
public String email;
public String firstName;
public String lastName;
请注意,您可能不需要来自 lombok 的 @Data 和 @EqualsAndHashCodeannotation 注释,因为它会生成 getter/setter
【讨论】:
以上是关于如何让 created_at 列自动生成创建日期时间,就像自动创建 ID 一样?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel 中更新 created_at 的列属性