如何让hibernate存储日期?

时间:2012-12-10 15:24:03

标签: mysql sql spring hibernate

我有一个Spring / Hibernate项目,我正在尝试将日期存储到数据库中,但它无法正常工作。它一定是蠢事但我不知道我做错了什么。

这是我的代码:

user.setFailedPasswordAnswerAttemptCount(0);
user.setLastLoginDate(new Date());
user.setIsOnline(true);

其他两个变量(failedPasswordAnswerAttemptCount和isOnline)正在被写入数据库而没有问题。我也尝试过只传递java.util.Date而不是java.sql.Timestamp ...相同的结果。以下是在用户对象上定义属性的方法:

private Date lastLoginDate;

@Temporal(TemporalType.TIMESTAMP)
@Column(name="last_login_date")
public Date getLastLoginDate() {
    return this.lastLoginDate;
}

public void setLastLoginDate(Date lastLoginDate) {
    this.lastLoginDate = lastLoginDate;
}

以下是列定义:

`last_login_date` datetime DEFAULT NULL

有任何帮助吗?我甚至不知道还有什么可以找,因为这应该有效。

有关错误的更多详细信息:休眠日志中没有错误或奇怪的消息。 hibernate日志显示了一个参数化查询,但它没有告诉我它实际上是在写什么。它看起来根本没有更新列。换句话说,如果已经有一个日期,它就不会改变,或者如果它是null,它就不会改变。

更新:我查看了日志,看起来hibernate会写出正确的数据,但是会立即再次写入错误的数据。我在日志中看到以下条目:

11:15:12.280 [http-bio-8080-exec-26] TRACE o.h.e.def.AbstractSaveEventListener - detached instance of: com.hi.model.User
11:15:12.280 [http-bio-8080-exec-26] TRACE o.h.e.def.DefaultMergeEventListener - merging detached instance

在那之后,我看到它将旧值重新用于lastLoginDate。

3 个答案:

答案 0 :(得分:0)

你为什么用

Date date = new Date();
user.setLastLoginDate(new Timestamp(date.getTime()));

而不仅仅是这个?

user.setLastLoginDate(new Date());

首先 - 你可能不想同时使用日期和时间戳。(例如收藏等)​​

  

Java平台库中有一些类可以扩展实例化   class并添加一个值组件。例如,java.sql.Timestamp   扩展java.util.Date并添加纳秒字段。等于实施   对于时间戳,确实违反了对称性,并且如果可能导致不稳定的行为   Timestamp和Date对象在同一个集合中使用,或以其他方式混合使用。   Timestamp类有一个免责声明警告程序员   混合日期和时间戳。虽然你不会遇到麻烦,只要你   让它们分开,没有什么可以阻止你混合它们,而且   产生的错误可能很难调试。 Timestamp类的这种行为是一个   错误,不应该被模仿。 (Bloch,Effective Java,2nd Ed。)

第二 - 我检查了你的例子,它在mysql-connector(5.1.21)/ hibernate(4.0.1)

上工作正常

我用arquillian集成测试准备了简单的测试项目(你需要在运行之前准备jboss): https://github.com/rchukh/StackOverflowTests/tree/master/13803848

如果你能提供更多的信息可能有帮助 - 休眠版,mysql版,mysql引擎版(MyISAM,InnoDB等) 否则,这可能只是一个配置错误。

答案 1 :(得分:0)

我发现了问题。我正在重构一些代码,看起来我正在这样做:

//get user object
User user = getUser();
//call a function which modifies user
functionModifiesUser();
//modify user
user.blah = blah;
entityManager.merge(user);

因此,当我尝试保存时,父函数有一个用户对象的陈旧副本。实际上,删除merge语句足以解决它。但是我已经重构了代码以将所有这些放在一个地方。

答案 2 :(得分:-1)

将列last_login_date设置为timestamp应该有效,至少对我有效。