如何使用 JPA 初始化表示其插入数据库的日期时间的实体字段?

Posted

技术标签:

【中文标题】如何使用 JPA 初始化表示其插入数据库的日期时间的实体字段?【英文标题】:How to initialize entities fields representing their datetime of insertion into database using JPA? 【发布时间】:2021-06-09 06:20:13 【问题描述】:

我的 JPA 实体有一个这样的字段:

@Column(nullable = false)
private LocalDateTime entryDateTime;

我希望在条目成功插入数据库时​​计算 entryDateTime

我想到了两种方法:

使用@PostPersist方法,在这种情况下我需要删除@Column(nullable = false)

使用@PrePersist 方法,在这种情况下@Column(nullable = false) 可以在那里,但如果插入失败怎么办?我不希望我的对象有 entryDateTime 然后初始化,所以我需要将它设置回 null。

设计实体可能会受到意见的影响,但我认为这个问题不是基于意见的。我正在寻找最有效的方法,我不需要删除@Column(nullable = false)。有没有办法做到这一点或更好的方法?还是我应该坚持我描述的其中一种方式?

【问题讨论】:

好吧,当插入失败时,您通常会在事务结束时得到一个异常,并且数据不会进入数据库。由于您不应该将实体保留太久(在大多数情况下最多直到事务结束),这应该不是问题。如果插入失败,您将一无所获。 - 但有一点需要注意:在实体中设置值意味着表示的时间是对象创建的时间,而不是持久化实际发生的时间。如果这是一个问题,您可能需要使用数据库默认值。 关于@PostPersist 的另一个想法:这将需要更新数据库以保持entryDateTime,因此您会在系统上增加更多负载,并且更新也可能会失败,因此您将拥有处理那个。这表明我认为@PrePersist 是更可行的选择。 如果你真的想从数据库中获取时间戳,你应该将 DEFAULT CURRENT_TIMESTAMP 添加到数据库表中。不要用 JPA 来做。 【参考方案1】:

您使用的是哪种 jpa 实现?

在 Hibernate 中,您可以使用注释字段

@CreationTimestamp

Hibernate Doc

在 Spring 中,您可以使用注释

@CreatedDate

Spring Doc

【讨论】:

我正在使用 OpenJPA。我不知道有这个选项。【参考方案2】:

在您的实体类中创建一个使用 PrePersist 注释的方法

例如:

public class UserEntity 
    private Date createdAt;

    ...

    @PrePersist
    public void prePersist() 
        createdAt = new Date();
    

应该可以的

【讨论】:

以上是关于如何使用 JPA 初始化表示其插入数据库的日期时间的实体字段?的主要内容,如果未能解决你的问题,请参考以下文章

JPA/Hibernate:如何为 @ManyToOne 插入默认值,其中值表示空条目

如何使用 JPA 和 Hibernate 在 UTC 时区中存储日期/时间和时间戳

日期时间JPA映射

如何从今天的日期获取下个月的日期并将其插入我的数据库中?

如何使用 JPA Query 将数据插入数据库?

如何使用 JPA 将 Java 日期存储到 Mysql 日期时间