持久化实体有两个Date字段,并且两者都在更新时更改,如何?

时间:2018-03-14 15:12:04

标签: java hibernate jpa

我遇到问题,两个日期字段更新到完全相同的日期,只有一个应该是。我试图弄清楚为什么会发生这种情况,以及我如何只更新我想要更新的一个日期字段,并将另一个保留原来的值。

我在MySQL数据库上使用Hibernate和JPA,如果这是原因的一部分。

我有一个看起来像这样的持久性实体:

@NamedQueries({
    @NamedQuery(name="MyObject.updateItem", query="UPDATE MyObject m SET m.item = :item, m.lastUpdate = :updated WHERE m.id = :id")
})
@Entity
@Table(name="entries")
public class MyObject implements Serializable
{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    private String item;

    @Column(columnDefinition = "TIMESTAMP", nullable = false)
    private Date dateCreated = new Date();
    @Column(columnDefinition = "TIMESTAMP", nullable = false)
    private Date lastUpdate = new Date();

    // after here standard constructors, getters, setters, etc.


}

当我从我的DAO拨打NamedQuery并提供正确的参数时,我发现lastUpdatedateCreated都已更改。这有什么理由,我该如何防止这种情况发生?这是因为我初始化实体类中的日期字段吗?

我使用TIMESTAMP列定义,因为我希望能够使用<>执行查询。

3 个答案:

答案 0 :(得分:0)

lastUpdate和dataCreated,aftare update有相同的值吗?

答案 1 :(得分:0)

我不知道这是否适合您,但这是我经常为我经常实施的所有实体做的事情。将PrePersist和PreUpdate函数添加到实体,以设置创建的和上次修改的时间。还可以尝试将@Temporal(TemporalType.TIMESTAMP)添加到每个日期字段中。

@PrePersist
public void prePersist() {
    this.dateCreated = new Date();
    this.lastUpdated = this.dateCreated;
}

@PreUpdate
public void preUpdate() {
    this.lastUpdated = new Date();
}

除此之外,我有点难过......

答案 2 :(得分:0)

所以我发现问题不是我的查询或我如何使用持久性,而是我如何构建数据库本身。

当我创建表格以包含对象的数据时,我没有为NOT NULL字段指定特定的默认值。

我原来的SQL CREATE语句看起来像这样。

CREATE TABLE IF NOT EXISTS `entries` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `item` VARCHAR(255) NOT NULL,
    `dateCreated` TIMESTAMP NOT NULL,
    `lastUpdate` TIMESTAMP NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

当MySQL服务器执行此语句时,它将第一个TIMESTAMP字段(在本例中为dateCreated)推迟使用默认值填充CURRENT_TIMESTAMP和属性{{1}这是我意想不到的。

我通过将字段的默认值更改为on update CURRENT_TIMESTAMP并更改我的DEFAULT '0000-00-00 00:00:00'语句以强制执行此默认值来更正此问题,因此我的新语句看起来像

CREATE TABLE

这显然允许我更新我想要的字段而不会导致其他字段自动更新。

我还不确定为什么MySQL会采用默认设置。我想它可能在文档中的某个地方。