Martin Dirichs
Martin Dirichs

Reputation: 113

Tracking last change to an object with @Version annotation in EclipseLink

Using JPA with EclipseLink, I would like to track the timestamp of the last update made to an entity instance. Assuming that this would be easy to combine with optimistic locking, I defined the entity as follows:

import javax.persistence.Version;
[...]

@Entity
public class Foo {
    @Id int id;
    @Version Timestamp lastChange;
    [...]
}

Updating a changed object is done with the following code:

EntityManager em = Persistence.createEntityManagerFactory("myConfiguration");
em.getTransaction().begin();
em.merge(foo);
em.getTransaction().commit();

I would expect that foo.lastChange would be set to the new timestamp each time an update to a changed instance is committed. However, while the field LASTCHANGE is updated in the database, it is not updated in the object itself. A second attempt to save the same object again thus fails with an OptimisticLockException. I know that EclipseLink allows to choose between storing the version-field in cache or directly in the object and I made sure that the configuration is set to IN_OBJECT.

The obvious question is: How to get the foo.lastChange field set to the updated timestamp value when saving to the database? Would

foo = em.find(Foo.class, foo.id);

be the only option? I suspect there must be a simpler way to this.

Upvotes: 2

Views: 1386

Answers (1)

JB Nizet
JB Nizet

Reputation: 691865

merge does not modify its argument. It copies the state from its argument to the attached version of its argument, and returns the attached version. You should thus use

foo = em.merge(foo);
// ...
return foo;

Upvotes: 3

Related Questions