20

thanks to you guys my knowlegde on hibernate has been improve dratiscally. now i hit a block here about current_timestamp. here is my codes

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

i want date_created to get the current_timestamp and i want the lastmodified to insert the time for each updates.apparently i can't have 2 current_timestamp fields on the same table.Is there other ways to achieve that? thanks for reading

black sensei
  • 6,528
  • 22
  • 109
  • 188

2 Answers2

57

This is not related to Hibernate per se. Your annotations as specified above tell Hibernate that the values are going to be generated by the database and thus need to be reloaded after entity is inserted / updated.

If that's the way you want to go with, you need to configure your database (by creating a trigger, for example) to populate date_created / last_modified columns as needed.

Another approach is to not mark those fields as generated and instead update them in your java code. If you're using JPA (via Hibernate EntityManager), it's rather trivial to do this via @PrePersist / @PreUpdate callback method:

@PreUpdate
@PrePersist
public void updateTimeStamps() {
    lastModified = new Date();
    if (dateCreated==null) {
      dateCreated = new Date();
    }
}
ChssPly76
  • 99,456
  • 24
  • 206
  • 195
  • @ChssPly76: why can't he have 2 current_timestamps in the same table, I don't know this to be a Hibernate limitation and from your answer you don't think so either. So it must be a business/dba limitation (though his use of "apparently I can't have..." sounds like he was surprised by that epiphany), what if he can't use EM then what could be his recourse. – non sequitor Nov 13 '09 at 01:51
  • Hibernate doesn't care; it's a database limitation - MySQL to be precise. I've no idea why they don't allow this; possibly because they thought that those timestamps would always be the same. – ChssPly76 Nov 13 '09 at 03:01
  • 1
    For ms sql server, timestamp means something completely different from datetime and it doesn't make sense to have multiple. – ashirley Dec 29 '09 at 17:59
  • 5
    It's best to do this via an EntityListener and an @Embeddable entity, so you can re-use your timestamp/audit code in all your entities. – Craig Ringer May 23 '12 at 01:48
  • 2
    @CraigRinger, you should add an answer to this! :) – Nick Spacek Aug 26 '12 at 01:49
  • 1
    As I see it the problem is the insertable=false part. This tells hibernate that the value for this column will not be touched by hibernate (not part of the INSERT statement). So as ChssPly76 stated already their are supposed to be generated somewhere else. Either created an insert trigger or change the flag to true and provide the value in a preInsert listener. For the lastModified column you could use the @Version annotation along with a temporal type to have hibernate generate a new timestamp each time the entity is updated. – Sebastian Götz Jan 13 '15 at 16:26
5

You could achieve the same thing with hibernates @CreationTimestampand @UpdateTimestamp annotations e.g.

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

@Column(name = "LAST_UPDATED")
@UpdateTimestamp
private LocalDateTime lastUpdated;
mrkernelpanic
  • 4,268
  • 4
  • 28
  • 52
  • 1
    This worked for me but I had to add `@Column(name = "CREATED",updatable = false, nullable = false)` or `created` would be null after an update – J.D Feb 19 '19 at 16:56