【问题标题】:hard time setting autogenerated time with hibernate JPA annotations使用休眠 JPA 注释很难设置自动生成的时间
【发布时间】:2009-11-12 21:57:01
【问题描述】:

感谢你们,我在休眠方面的知识得到了极大的提高。 现在我在这里遇到了关于 current_timestamp 的问题。 这是我的代码

@Column(name="DATE_CREATED", insertable=false, updatable=false, columnDefinition="timestamp default current_timestamp")
@org.hibernate.annotations.Generated(value=GenerationTime.INSERT)
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date dateCreated;

@Column(name="LAST_MODIFIED", insertable=false, updatable=false, columnDefinition="datetime")
@org.hibernate.annotations.Generated(value=GenerationTime.ALWAYS)
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date lastModified;

我希望 date_created 获取 current_timestamp 并且我希望 lastmodified 插入每次更新的时间。显然我不能在同一个表上拥有 2 个 current_timestamp 字段。还有其他方法可以实现吗?感谢阅读

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    这与 Hibernate 本身无关。上面指定的注释告诉 Hibernate,这些值将由数据库生成,因此需要在插入/更新实体后重新加载。

    如果您想采用这种方式,则需要配置数据库(例如,通过创建触发器)以根据需要填充 date_created / last_modified 列。

    另一种方法是不将这些字段标记为已生成,而是在您的 java 代码中更新它们。如果您使用的是 JPA(通过 Hibernate EntityManager),那么通过 @PrePersist / @PreUpdate 回调方法执行此操作相当简单:

    @PreUpdate
    @PrePersist
    public void updateTimeStamps() {
        lastModified = new Date();
        if (dateCreated==null) {
          dateCreated = new Date();
        }
    }
    

    【讨论】:

    • @ChssPly76:为什么他不能在同一张表中有 2 个 current_timestamps,我不知道这是 Hibernate 限制,从你的回答中你也不这么认为。所以这一定是一个业务/dba 限制(尽管他使用“显然我不能拥有......”听起来他对那个顿悟感到惊讶),如果他不能使用 EM,那么他可以求助于什么。
    • 对于 ms sql server,timestamp 意味着与 datetime 完全不同的东西,有多个没有意义。
    • 最好通过 EntityListener 和 @Embeddable 实体来执行此操作,这样您就可以在所有实体中重复使用时间戳/审核代码。
    • @CraigRinger,您应该为此添加答案! :)
    • 在我看来,问题在于 insertable=false 部分。这告诉 hibernate 该列的值不会被 hibernate 触及(不是 INSERT 语句的一部分)。因此,正如 ChssPly76 所述,它们应该在其他地方生成。创建插入触发器或将标志更改为 true 并在 preInsert 侦听器中提供值。对于 lastModified 列,您可以使用 @Version 注释和时间类型让休眠在每次实体更新时生成一个新的时间戳。
    【解决方案2】:

    您可以使用休眠 @CreationTimestamp@UpdateTimestamp 注释来实现相同的目的,例如

    @Column(name = "CREATED")
    @CreationTimestamp
    private LocalDateTime created;
    
    @Column(name = "LAST_UPDATED")
    @UpdateTimestamp
    private LocalDateTime lastUpdated;
    

    【讨论】:

    • 这对我有用,但我必须添加 @Column(name = "CREATED",updatable = false, nullable = false)created 在更新后将为空
    猜你喜欢
    • 2012-08-05
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 2015-04-05
    • 1970-01-01
    • 2014-03-17
    相关资源
    最近更新 更多