我遇到了两个日期字段更新到完全相同的日期的问题,而只有一个应该更新。我试图弄清楚为什么会发生这种情况,以及如何只更新我要更新的一个日期字段,而将另一个字段保留为其原始值。
我在MySQL数据库上使用带有JPA的Hibernate,以防这是部分原因。
我有一个持久性实体,看起来像这样:
@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
并提供正确的参数时,我发现lastUpdate
和dateCreated
都发生了变化。这有什么原因吗,我怎样才能防止这种情况发生?这是因为我在实体类中初始化了结束日期字段吗?
我正在使用TIMESTAMP
列定义,因为我希望能够使用 <
或 >
执行查询。
lastUpdate 和 dataCreated,aftare update 具有相同的值?
这是否适合您,但这是我通常为我经常实现的所有实体所做的。向实体添加预持久和预更新功能,以设置创建和上次修改时间。此外,请尝试将@Temporal(TemporalType.TIMESTAMP(添加到每个日期字段中。
@PrePersist
public void prePersist() {
this.dateCreated = new Date();
this.lastUpdated = this.dateCreated;
}
@PreUpdate
public void preUpdate() {
this.lastUpdated = new Date();
}
除此之外,我有点难倒...
所以我发现问题不在于我的查询或我如何使用持久性,而在于我如何构建数据库本身。
当我创建包含对象数据的表时,我没有为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
和属性on update CURRENT_TIMESTAMP
填充它,这是我出乎意料的。
我通过将字段的默认值更改为 DEFAULT '0000-00-00 00:00:00'
并更改我的 CREATE TABLE
语句来强制使用此默认值来纠正此问题,因此我的新语句看起来像
CREATE TABLE IF NOT EXISTS `entries` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`item` VARCHAR(255) NOT NULL,
`dateCreated` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
`lastUpdate` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这显然允许我更新所需的字段,而不会导致另一个字段自动更新。
我仍然不确定为什么MySQL假设它所做的默认值。我想它可能在文档中的某个地方。