2009-12-09 10 views
7

Mi sono imbattuto in domande simili su StackOverflow, ho provato le soluzioni, ma non ho trovato una risposta.EclipseLink Chiamata JPA `@ PreUpdate` non persistente

Sto usando una strategia JPA abbastanza comune per impostare gli ultimi tempi modificati su alcune entità. Imposta le colonne e i campi, quindi contrassegna un metodo con @PreUpdate e lascia che sia uguale all'ora corrente.

Il problema è che posso vedere nel debugger che il metodo viene chiamato e che il campo è in fase di aggiornamento, tuttavia nei registri di DB vedo solo una chiamata SQL a UPDATE il campo modificato che NON include un UPDATE per il campo timestamp.

Complementare ulteriormente le cose @PrePersist funziona perfettamente, solo @PreUpdate mostra questo comportamento.

La spiegazione più vicina che ho trovato finora è in questo LINK.

domande simili a: # 1.725.699 e # 1745890

Sto usando EclipseLink v2 e JPA v1 per la compatibilità con GlassFish v2.

Ho tentato di utilizzare entrambe le annotazioni direttamente sui metodi nella classe Entity, nonché un EntityListener associato alla classe Entity con l'annotazione @EntityListener.

Ho il sospetto che si tratti di un bug in EclipseLink, ma non posso provarlo.

Bug o non mi piacerebbe molto che questa semplice operazione funzioni. C'è qualcosa di sbagliato in questa implementazione? Si tratta di un problema noto in EclipseLink? Si tratta di un problema noto in JPA? C'è un modo per aggirare questo?

A corto di andare al database e utilizzare i trigger, c'è un percorso alternativo per consentire al mio codice Java di impostare il timestamp updated_on?

Grazie per il consiglio!

Segmenti di codice seguiti.

campi

Entità:

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

metodi di aggiornamento annotati:

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

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

risposta

4

il collegamento fornito si descrive esattamente la situazione: per il controllo sporca, campi aggiornati vengono rilevati prima che il metodo viene chiamato @PreUpdate e le modifiche nel metodo @PreUpdate non vengono più rilevate. Questo è probabilmente fatto per motivi di prestazioni, perché i controlli sporchi possono essere molto costosi su grafici di oggetti di grandi dimensioni. Sembra che in questo momento le tue scelte siano utilizzare un meccanismo specifico del provider (DescriptorEvent) o passare a Hibernate.

+0

Felix - Grazie per il chiarimento. Pensavo che fosse quello che stavo vedendo. Vedo come implementare la gestione di DescriptorEvent, quasi facile come annotare alcuni metodi. Devi solo trovare il file XML giusto per aggiungere il gestore. Grazie ancora! – Freiheit

+0

Hi Freiheit, sto affrontando lo stesso problema in questo momento, ti dispiacerebbe condividere il tuo codice DescriptorEvent come esempio? :) grazie – sunnycmf

+0

@Freiheit piacerebbe vedere anche la soluzione. Grazie in anticipo. –

3

Mybe un po 'tardi, ma per completezza di informazioni questo non è un bug, ma un comportamento documentato: tipi

Data o Calendario sono assunti NON di essere mutevole per impostazione predefinita, se si desidera per chiamare i metodi impostati su Data o Calendario, la mappatura deve essere impostata su @Mutable.

Per i tipi di data e il calendario la persistenza proprietà "eclipselink.temporal.mutable" globale può anche essere impostato su "true".

così, o annotare

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

o definire

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

in persistence.xml

+0

Grazie mille Michele, è lavorare con me come un incantesimo. –

+0

Prego :) –

+0

Ho aggiunto questa annotazione ma ancora non funziona ([vedi la mia domanda] (https://stackoverflow.com/questions/47081932/prepersist-not-working-with-mappedsuperclass-in-hibernate -Spring-ambiente)). Qualche idea del perché? – displayname

Problemi correlati