Setting a JPA timestamp column to be generated by the database?

有些话、适合烂在心里 提交于 2019-11-28 16:48:32

I fixed the issue by changing the code to

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

So the timestamp column is ignored when generating SQL inserts. Not sure if this is the best way to go about this. Feedback is welcome.

Matt Luongo

I realize this is a bit late, but I've had success with annotating a timestamp column with

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

This should also work with CURRENT_DATE and CURRENT_TIME. I'm using JPA/Hibernate with Oracle, so YMMV.

@Column(nullable = false, updatable = false)
@CreationTimestamp
private Date created_at;

this worked for me. more info

I have this working well using JPA2.0 and MySQL 5.5.10, for cases where I only care about the last time the row was modified. MySQL will create a timestamp on first insertion, and every time UPDATE is called on the row. (NOTE: this will be problematic if I cared whether or not the UPDATE actually made a change).

The "timestamp" column in this example is like a "last-touched" column.x`

The code below uses a separate column "version" for optimistic locking.

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;
}

(NOTE: @Version doesn't work on a MySQL "DATETIME" column, where the attribute type is "Date" in the Entity class. This was because Date was generating a value down to the millisecond, however MySQL was not storing the millisecond, so when it did a comparison between what was in the database, and the "attached" entity, it thought they had different version numbers)

From the MySQL manual regarding TIMESTAMP :

With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.

I do not think that every database has auto-update timestamps (e.g. Postgres). So I've decided to update this field manually everywhere in my code. This will work with every database:

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

There are reasons to use triggers, but for most projects, this is not one of them. Triggers dig you even deeper into a specific database implementation.

MySQL 5.6.28 (Ubuntu 15.10, OpenJDK 64-Bit 1.8.0_66) seems to be very forgiving, not requiring anything beyond

@Column(name="LastTouched")

MySQL 5.7.9 (CentOS 6, OpenJDK 64-Bit 1.8.0_72) only works with

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

not:

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

My other system info (identical in both environments)

  • hibernate-entitymanager 5.0.2
  • hibernate-validator 5.2.2
  • mysql-connector-java 5.1.38
@Column(name = "LastTouched", insertable = false, updatable = false, columnDefinition = "TIMESTAMP default getdate()")
@Temporal(TemporalType.TIMESTAMP)
private Date LastTouched;`enter code here`
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!