【问题标题】:How to get hibernate to store a date?如何让休眠来存储日期?
【发布时间】:2012-11-28 00:53:53
【问题描述】:

我有一个 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 确实写入了正确的数据,但随后立即再次写入了不正确的数据。我在日志中看到以下条目:

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。

【问题讨论】:

  • 什么是失败?只是写NULL吗?它会产生错误消息吗?是不是在日志里写了些奇怪的东西?
  • @DonalFellows 我在帖子末尾添加了更多细节。
  • 映射问题?您是否尝试将注解 @column 放到字段而不是函数中?
  • @JulienMay 我试过了,没用。
  • 我在我的应用程序中几乎就是这样做的。我认为 @Column 注释中的长度定义看起来很可疑。尝试删除它,然后使用 user.setLastLoginDate(new Date()); - 为我工作。此外,如果您为 org.hibernate 设置 TRACE 日志记录,它会显示它用于插入的参数值。

标签: mysql sql spring hibernate


【解决方案1】:

last_login_date 列设置为timestamp 应该可以,至少对我有用。

【讨论】:

  • 嗯,是的,我知道它应该可以工作。问题是为什么它不起作用?我不太确定你认为这是对我问题的回答。
  • 那么,当您的列是datetime 类型时,为什么要创建Timestamp 而不是Date
  • java.sql.Timestamp 只是比日期更具体。它是 Date 的子类。我换了个方法试了,没效果。
【解决方案2】:

你为什么使用

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

不只是这个?

user.setLastLoginDate(new Date());

首先 - 您可能不想同时使用 Date 和 Timestamp。(例如,用于集合等)

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

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

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

如果您可以提供更多信息,它可能会有所帮助 - hibernate 版本、mysql 版本、mysql 引擎(MyISAM、InnoDB 等) 否则可能只是配置错误。

【讨论】:

  • 一开始我是用第二种方式做的。我将其更改为第一种方式(使用 java.sql.Timestamp)以查看是否存在仅通过日期的问题。我会尽快回复您配置详细信息...
【解决方案3】:

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

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

所以当我试图保存它时,父函数有一个用户对象的旧副本。实际上,删除合并语句就足以修复它。但是我已经重构了代码以将所有这些都放在一个地方。

【讨论】:

    猜你喜欢
    • 2012-12-26
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 2017-09-07
    • 2014-07-23
    • 2011-04-08
    相关资源
    最近更新 更多