我遇到问题,两个日期字段更新到完全相同的日期,只有一个应该是。我试图弄清楚为什么会发生这种情况,以及我如何只更新我想要更新的一个日期字段,并将另一个保留原来的值。
我在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
并提供正确的参数时,我发现lastUpdate
和dateCreated
都已更改。这有什么理由,我该如何防止这种情况发生?这是因为我初始化实体类中的日期字段吗?
我使用TIMESTAMP
列定义,因为我希望能够使用<
或>
执行查询。
答案 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会采用默认设置。我想它可能在文档中的某个地方。