【问题标题】:Hibernate @Generated(GenerationType.ALWAYS) is not populating my timestamps on updateHibernate @Generated(GenerationType.ALWAYS) 没有在更新时填充我的时间戳
【发布时间】:2016-10-07 16:43:21
【问题描述】:

我的实体上有 2 个时间戳,它们由 mySQL 填充,如下所示:

created_datetimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, last_modified_datetimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

我已经像这样注释了我的实体字段:

@Column(name = "created_date", updatable=false, insertable=false)
@Generated(GenerationTime.INSERT)
Date createdDate;

@Column(name = "last_modified_date", updatable=false, insertable=false)
@Generated(GenerationTime.ALWAYS)
Date lastModifiedDate;

当我保存一个新实体时,实体字段随后会填充由 mySQL 填充的值。

但是,当我更新我的实体时,这些字段随后为空。 createdDate 和 lastModifiedDate。

我尝试了其他几种选择:

  1. 我已包含 @Temporal 注释 - 没有变化
  2. 我删除了可更新和可插入属性,删除了@Generated 注释,并在设置代码日期的方法上使用了@PrePersist 和@PreUpdate - 这会在保存后立即产生空字段,并且在更新后也会立即产生空字段。
  3. 在插入/更新后立即在我的实体上执行“获取” - 这显然不起作用,因为实体已经在会话中,因此 hibernate 不执行实际的数据库查询。

我需要的是在保存后和更新后立即用有效值填充两个字段。

这是用于更新的 DAO/Repository 代码 - 全部包装在服务层的事务中。这段代码实际上不是我写的,是一个初级开发人员写的,我认为它需要重构,但我没有看到任何可能导致我所看到的内容:

BaseHibernateDaoImpl:

protected HibernateTemplate hibernateTemplate;

public void update(Object object) {
    hibernateTemplate.update(object);
}

UserCommentDaoImpl(扩展 BaseHibernateDaoImpl):

public void saveOrUpdate(UserComment userComment, UserAccount userAccount){
    UserComment existing  = getBy(userComment.getId(),userAccount,ActiveStatus.ACTIVE);
    if(existing != null) {
        evict(existing);
        update(userComment);
    } else {
        save(userComment);
    }
}

相同的“saveOrUpdate”方法用于创建/保存(填充时间戳)和更新(不填充)。

我正在使用:

  • mySQL java 连接器版本:5.1.38
  • 休眠版本:5.1.0.Final
  • 春季版:4.2.5.RELEASE
  • Java 版本:1.8

【问题讨论】:

  • 更新实体的代码是什么?
  • @JBNizet 我添加了您要求的相关代码

标签: java hibernate


【解决方案1】:

看来问题的原因是我们不推荐使用休眠。

我们的休息控制器正在从 DTO 中的字段构建一个新的 UserComment 实例。此构建实例中的时间戳为空。当我们的 DAO “更新”对象时,它正在从数据库中查询持久化对象,然后驱逐该对象并在从 DTO 构建的实例上调用“hibernateSession.update”(换句话说,该实例不在会话)。

当我修改代码以保留会话实例,并从构建的实例中复制修改后的字段,然后在会话实例上调用“更新”时,时间戳开始按照我的预期填充并需要它们。

推荐的休眠使用说明(所以我读到)永远不应该在不是首先从会话加载的对象上调用更新。应该加载持久化实例,然后修改,然后更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-18
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    相关资源
    最近更新 更多