English 中文(简体)
EclipseLink JPA `@PreUpdate` call not persisting
原标题:

I ran into some similar questions on StackOverflow, tried the solutions, but did not find an answer.

I am using a fairly common JPA strategy to set last modified times on some entities. Set up the columns and the fields, then tag a method with @PreUpdate and let it set them equal to the current time.

The problem is that I can see in the debugger that the method is being called and that the field is being updated, however in my DB logs I only see a SQL call to UPDATE the changed field that does NOT include an UPDATE for the timestamp field.

Complicating things further @PrePersist works perfectly, only @PreUpdate exibits this behaviour.

The closest explanation I ve found so far is at this LINK.

Similar questions at: #1725699 and #1745890

I am using EclipseLink v2 and JPA v1 for compatibility with GlassFish v2.

I have attempted using both annotations directly on methods in the Entity class as well as an EntityListener attached to the Entity class with the @EntityListener annotation.

I suspect this is a bug in EclipseLink, but I can t prove it.

Bug or not I would very much like this simple operation to work. Is there anything wrong with this implementation? Is this a known issue in EclipseLink? Is this a known issue in JPA? Is there a way around this?

Short of going to the database and using triggers, is there an alternate path to let my Java code set the updated_on timestamp?

Thanks for the advice!

Code snippets follow.

Entity fields:

@Column(name = "updated_on")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedOn;
@Column(name = "created_on")
@Temporal(TemporalType.TIMESTAMP)
private Date createdOn;

Annotated update methods:

@PreUpdate
public void setUpdatedOn(Timestamped object) {
    object.setUpdatedOn(new Date());
}

@PrePersist
public void setCreatedOn(Timestamped object) {
    if (object.getCreatedOn()==null) {
      object.setCreatedOn(new Date());
    }
}
最佳回答

The link you provide describes exactly your situation: for the dirty check, updated fields are detected before the @PreUpdate method is called and changes in the @PreUpdate method are not detected any more. This is probably done for performance reasons because dirty checks can be very expensive on large object graphs. It seems right now your choices are to use a provider-specific mechanism (DescriptorEvent) or to switch to Hibernate.

问题回答

Mybe a bit late, but for completeness of information this is NOT a bug, but a documented behavior:

Date or Calendar types are assumed NOT to be mutable by default, if it is desired to call the set methods on the Date or Calendar, then the mapping must be set to be @Mutable.

For Date and Calendar types the global persistence property "eclipselink.temporal.mutable" can also be set to "true".

so, either annotate

@Mutable
@Column(name = "updated_on")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedOn;

or define

<property name="eclipselink.temporal.mutable" value="true" />

in persistence.xml





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签