Hibernate @Generated(GenerationType.ALWAYS)没有在更新

时间:2016-06-07 16:57:52

标签: java hibernate

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

created_date时间戳NOT NULL DEFAULT CURRENT_TIMESTAMP,   last_modified_date时间戳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填充的值。

但是,当我更新我的实体时,这些字段随后为空。都创建了Date和lastModifiedDate。

我尝试过其他几种选择:

  1. 我收录了@Temporal注释 - 没有更改
  2. 我删除了可更新和可插入的属性,删除了@Generated注释,并在一个在代码中设置日期的方法上使用@PrePersist和@PreUpdate - 这会在保存后立即生成空字段,也会在更新后立即生成。 / LI>
  3. 在插入/更新后立即对我的实体执行“获取” - 这显然不起作用,因为实体已经在会话中,因此hibernate不执行实际的数据库查询。
  4. 我需要的是两个字段在保存后立即填充有效值,并在更新后立即填充。

    这是用于更新的DAO /存储库代码 - 全部包含在服务层的事务中。我实际上没有写这个代码,一个初级开发人员做了,我看到它需要重构,但我没有看到任何可能导致我所看到的:

    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
    • Hibernate版本:5.1.0.Final
    • 春季版:4.2.5.RELEASE
    • Java版本:1.8

1 个答案:

答案 0 :(得分:0)

似乎我们不建议使用hibernate来解决问题。

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

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

推荐的hibernate用法判断(所以我读),永远不应该在未首先从会话加载的对象上调用更新。应该加载持久化实例,然后进行修改,然后更新。