JPA EntityManager - 使用合并生成默认值?

JPA EntityManager - Using merge to generate default value?

我有一个 JPA 实体,它有一个创建日期和一个修改日期列。在creation/persist,创建日期和修改日期都是由数据库中给定的默认值生成的,这是一个时间戳。创建有效,但是,当我尝试执行 update/merge 时,我不知道如何使用数据库中的默认值更改修改日期。有什么建议吗?这是当前设置:

....
@Temporal(TemporalType.DATE)
@Column(name="CREATED_DATE", insertable = false, updatable = false)
private Date createdDate;

@Temporal(TemporalType.DATE)
@Column(name="MODIFIED_DATE", insertable = false)
private Date modifiedDate;
....

-

public Database changeDate(Database oldValues)
    Database newvalues = new Database();
    ....
    newValues.setCreatedDate(oldValues.getCreatedDate);
    //newValues.setModifiedDate(); <-- (Should use the default value in the database)
    ....
    em.merge(newValues); <-- (EntityManager)
    em.getTransaction().commit();

** 以防万一我没有说清楚,我只是不知道如何使用数据库中设置的默认值进行更新。

您想将 Null 值设置为日期。请在您的日期注释中添加可为 nullable 属性。它会起作用。

将其添加到您的注释中 nullable = true

@Temporal(TemporalType.DATE)
@Column(name="CREATED_DATE",nullable = true, insertable = false, updatable = false)
private Date createdDate;

@Temporal(TemporalType.DATE)
@Column(name="MODIFIED_DATE", nullable = true, insertable = false)
private Date modifiedDate;

如果我对问题的理解正确,您希望确保 MODIFIED_DATE 列始终设置为 CURRENT_TIMESTAMP。然后,当一个数据库实体被更新并且它的其他字段被修改时,MODIFIED_DATE 列将被设置为 CURRENT_TIMESTAMP.

我假设您的数据库 table 看起来像这样:

CREATE TABLE Database (
    ID int NOT NULL,
    CREATED_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    MODIFIED_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)

您要做的是向您的数据库实体添加一个@PreUpdate 方法class,并让它每次都将 modifiedDate 属性设置为一个新的 Date()。然后,每当对实体进行更新时,MODIFIED_DATE 列将设置为新日期!

这是一个例子:

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

尝试一个简单的例子,看看它是如何工作的:

em.getTransaction().begin();
Database db = new Database(1, "First Value");
em.persist(db);
em.getTransaction().commit();

em.getTransaction().begin();
Database db2 = em.find(Database.class, 1);
db2.setValue("New Value!");
em.getTransaction().commit();

有一个注释可以使用 javax.persistence.Version

@Column(name="CREATED_DATE", updatable = false)
private java.sql.Timestamp createdDate = new java.sql.Timestamp(System.currentTimeMillis());

@Version
@Column(name="MODIFIED_DATE")
private java.sql.Timestamp modifiedDate;

两个字段只需要getter,不需要setter。 JPA 将自行比较和更新时间戳值。否则,如果您依赖数据库为您生成它,您不妨尝试 @GeneratedValue(strategy = GenerationType.IDENTITY) 或 AUTO,但我很确定这在 Hibernate 中不起作用。也许它会在其他 JPA 提供程序中工作。在 Hibernate 中,AUTO 的值总是回退到 SEQUENCE,因此该策略不可能起作用。