78

DATETIME在我的 SQL Server 2000 数据库中,我有一个类型为lastTouched设置getdate()为默认值/绑定的时间戳(在函数中而不是数据类型中)列。

我正在使用 Netbeans 6.5 生成的 JPA 实体类,并在我的代码中有这个

@Basic(optional = false)
@Column(name = "LastTouched")
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

但是,当我尝试将对象放入我得到的数据库时,

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.generic.Stuff.lastTouched

我尝试将 to 设置@Basic(optional = true),但这会引发异常,指出数据库不允许列null的值TIMESTAMP,这是设计上不允许的。

ERROR JDBCExceptionReporter - Cannot insert the value NULL into column 'LastTouched', table 'DatabaseName.dbo.Stuff'; column does not allow nulls. INSERT fails.

我以前让它在纯 Hibernate 中工作,但我已经切换到 JPA 并且不知道如何告诉它这个列应该在数据库端生成。请注意,我仍然使用 Hibernate 作为我的 JPA 持久层。

4

12 回答 12

67

我通过将代码更改为

@Basic(optional = false)
@Column(name = "LastTouched", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

因此在生成 SQL 插入时会忽略时间戳列。不确定这是否是解决此问题的最佳方法。欢迎反馈。

于 2009-05-01T18:57:02.813 回答
52

我意识到这有点晚了,但我已经成功地用注释时间戳列

@Column(name="timestamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

这也应该与CURRENT_DATEand一起使用CURRENT_TIME。我将 JPA/Hibernate 与 Oracle 一起使用,所以是 YMMV。

于 2010-06-24T06:20:15.483 回答
23
@Column(nullable = false, updatable = false)
@CreationTimestamp
private Date created_at;

这对我有用。 更多信息

于 2017-12-29T09:27:50.570 回答
9

添加@CreationTimestamp注释:

@CreationTimestamp
@Column(name="timestamp", nullable = false, updatable = false, insertable = false)
private Timestamp timestamp;
于 2020-01-06T10:31:58.310 回答
5

对于我只关心最后一次修改行的情况,我使用 JPA2.0 和 MySQL 5.5.10 可以很好地工作。MySQL 将在第一次插入时创建一个时间戳,并且每次在该行上调用 UPDATE。(注意:如果我关心 UPDATE 是否确实进行了更改,这将是有问题的)。

此示例中的“时间戳”列就像“最后一次触摸”列.x`

下面的代码使用单独的列“版本”进行乐观锁定。

private long version;
private Date timeStamp

@Version
public long getVersion() {
    return version;
}

public void setVersion(long version) {
    this.version = version;
}

// columnDefinition could simply be = "TIMESTAMP", as the other settings are the MySQL default
@Column(name="timeStamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
public Date getTimeStamp() {
    return timeStamp;
}

public void setTimeStamp(Date timeStamp) {
    this.timeStamp = timeStamp;
}

(注意:@Version 不适用于 MySQL“DATETIME”列,其中 Entity 类中的属性类型为“Date”。这是因为 Date 生成的值精确到毫秒,但是 MySQL 没有存储毫秒,所以当它对数据库中的内容和“附加”实体进行比较时,它认为它们有不同的版本号)

从 MySQL 手册中关于 TIMESTAMP

With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
于 2011-04-28T03:22:26.023 回答
4

我不认为每个数据库都有自动更新时间戳(例如 Postgres)。所以我决定在我的代码中的任何地方手动更新这个字段。这将适用于每个数据库:

thingy.setLastTouched(new Date());
HibernateUtil.save(thingy);

使用触发器是有原因的,但对于大多数项目来说,这不是其中之一。触发器可以让您更深入地了解特定的数据库实现。

MySQL 5.6 .28 (Ubuntu 15.10, OpenJDK 64-Bit 1.8.0_66) 似乎非常宽容,不需要任何超越

@Column(name="LastTouched")

MySQL 5.7 .9 (CentOS 6, OpenJDK 64-Bit 1.8.0_72) 仅适用于

@Column(name="LastTouched", insertable=false, updatable=false)

不是:

FAILED: removing @Temporal
FAILED: @Column(name="LastTouched", nullable=true)
FAILED: @Column(name="LastTouched", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")

我的其他系统信息(在两个环境中都相同)

  • 休眠实体管理器 5.0.2
  • 休眠验证器 5.2.2
  • mysql-connector-java 5.1.38
于 2016-02-15T19:49:37.033 回答
4

如果你用@DynamicInsert例如标记你的实体

@Entity
@DynamicInsert
@Table(name = "TABLE_NAME")
public class ClassName implements Serializable  {

Hibernate 将生成没有null值的 SQL。然后数据库将插入自己的默认值。这确实会影响性能,请参阅 [Dynamic Insert][1]。

于 2020-01-10T15:36:12.947 回答
3

我将这个发布给人们在使用 MySQL 和 Java Spring Boot JPA 时寻找答案,就像@immanuelRocha 说的那样,在 Spring 中只有 @CreationTimeStamp 到 @Column,并且在 MySQL 中将默认值设置为“CURRENT_TIMESTAMP”。

在 Spring 中只添加以下行:

@Column(name = "insert_date")
@CreationTimestamp
private Timestamp insert_date;

于 2020-03-09T17:47:48.760 回答
3

如果您在Java 8 和 Hibernate 5 或 Spring Boot JPA中进行开发,那么直接在您的 Entity 类中使​​用以下注解。Hibernate 从 VM 获取当前时间戳,并将日期和时间插入数据库。

public class YourEntity {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String name;
 
    @CreationTimestamp
    private LocalDateTime createdDateTime;
 
    @UpdateTimestamp
    private LocalDateTime updatedDateTime;
 
    …
}
于 2020-08-25T09:47:14.953 回答
2

这也适用于我: -

@Temporal(TemporalType.TIMESTAMP)   
@Column(name = "CREATE_DATE_TIME", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
public Date getCreateDateTime() {
    return createDateTime;
}

public void setCreateDateTime(Date createDateTime) {
    this.createDateTime = createDateTime;
}
于 2020-01-31T06:02:46.110 回答
0
@Column(name = "LastTouched", insertable = false, updatable = false, columnDefinition = "TIMESTAMP default getdate()")
@Temporal(TemporalType.TIMESTAMP)
private Date LastTouched;`enter code here`
于 2019-06-17T10:36:28.507 回答
-1

这对我有用:

@Column(name = "transactionCreatedDate", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
于 2019-09-16T07:10:31.793 回答