Racco Taco
Racco Taco

Reputation: 15

JPA EntityManager - Using merge to generate default value?

I have one JPA entity that has a created date and a modified date column. On creation/persist, both the created date and modified date are generated by the default value given in the database, which is a timestamp. The creation works, however, when I try to do an update/merge, I cannot figure out how to change the modified date by using the default value in the database. Any advice? This is the current setup:

....
@Temporal(TemporalType.DATE)
@Column(name="CREATED_DATE", insertable = false, updatable = false)
private Date createdDate;

@Temporal(TemporalType.DATE)
@Column(name="MODIFIED_DATE", insertable = false)
private Date modifiedDate;
....

-

public Database changeDate(Database oldValues)
    Database newvalues = new Database();
    ....
    newValues.setCreatedDate(oldValues.getCreatedDate);
    //newValues.setModifiedDate(); <-- (Should use the default value in the database)
    ....
    em.merge(newValues); <-- (EntityManager)
    em.getTransaction().commit();

** Just in case I didn't make myself clear, I just don't know how to make it update with the default value set in the database.

Upvotes: 0

Views: 1280

Answers (3)

coladict
coladict

Reputation: 5095

There is an annotation you could use javax.persistence.Version

@Column(name="CREATED_DATE", updatable = false)
private java.sql.Timestamp createdDate = new java.sql.Timestamp(System.currentTimeMillis());

@Version
@Column(name="MODIFIED_DATE")
private java.sql.Timestamp modifiedDate;

Both fields need only have a getter, no setter. The JPA will compare and update the timestamp value on it's own. Otherwise if you rely on the database to generate it for you, you might as well try @GeneratedValue(strategy = GenerationType.IDENTITY) or AUTO, but I'm pretty sure that won't work in Hibernate. Maybe it will work in other JPA providers. In Hibernate, the AUTO is value always falls-back to SEQUENCE, so no chance of that strategy working.

Upvotes: 0

Will Dazey
Will Dazey

Reputation: 273

If I understand the question correctly, you want to make sure that the MODIFIED_DATE column always gets set to the CURRENT_TIMESTAMP. Then, when a Database entity gets updated and it's other fields modified, the MODIFIED_DATE column will be set to the CURRENT_TIMESTAMP.

I assume that your DB table looks something like this:

CREATE TABLE Database (
    ID int NOT NULL,
    CREATED_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    MODIFIED_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)

What you want to do is add a @PreUpdate method to your Database entity class and have it set the modifiedDate attribute to a new Date() each time. Then, whenever an update is made to the entity, the MODIFIED_DATE column will be set to a new date!

Here is an example:

@PreUpdate
protected void onUpdate() {
    modifiedDate = new Date();
}

Try a simple example and see how it works:

em.getTransaction().begin();
Database db = new Database(1, "First Value");
em.persist(db);
em.getTransaction().commit();

em.getTransaction().begin();
Database db2 = em.find(Database.class, 1);
db2.setValue("New Value!");
em.getTransaction().commit();

Upvotes: 0

Kumaresan Perumal
Kumaresan Perumal

Reputation: 1956

you want to set Null value to date. please add nullable property in your date annotation. it will work.

add it in your annotation nullable = true

@Temporal(TemporalType.DATE)
@Column(name="CREATED_DATE",nullable = true, insertable = false, updatable = false)
private Date createdDate;

@Temporal(TemporalType.DATE)
@Column(name="MODIFIED_DATE", nullable = true, insertable = false)
private Date modifiedDate;

Upvotes: 1

Related Questions