2011-11-20 8 views
14

Vorrei aggiungere un campo Date/DateTime/Timestamp su un oggetto entity, che verrà creato automaticamente quando l'entità viene creata/persistita e impostata su "now", per non essere mai più aggiornata.Come creare un campo Data/Timestamp generato automaticamente in un gioco!/JPA?

Altri casi d'uso comprendevano campi che venivano sempre aggiornati per contenere l'ultima data di modifica dell'entità.

Ho utilizzato tali requisiti in the mysql schema.

Qual è il modo migliore per farlo in Play!/JPA?

+0

Avete bisogno di dire che il database dovrebbe impostare il valore di data "ora" o può farlo l'APC? –

+0

@PiotrNowicki - può essere fatto da JPA. Attualmente lo sto facendo all'interno del mio codice applicazione. – ripper234

risposta

32

C'è uno snippet di codice che è possibile adattare per ottenere ciò che si desidera. Date un'occhiata:

// Timestampable.java 

package models; 

import java.util.Date; 

import javax.persistence.Column; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.MappedSuperclass; 
import javax.persistence.PrePersist; 
import javax.persistence.PreUpdate; 
import javax.persistence.Version; 

import play.db.ebean.Model; 

@MappedSuperclass 
public class Timestampable extends Model { 

    @Id 
    @GeneratedValue 
    public Long id; 

    @Column(name = "created_at") 
    public Date createdAt; 

    @Column(name = "updated_at") 
    public Date updatedAt; 

    @Version 
    public int version; 

    @Override 
    public void save() { 
    createdAt(); 
    super.save(); 
    } 

    @Override 
    public void update() { 
    updatedAt(); 
    super.update(); 
    } 

    @PrePersist 
    void createdAt() { 
    this.createdAt = this.updatedAt = new Date(); 
    } 

    @PreUpdate 
    void updatedAt() { 
    this.updatedAt = new Date(); 
    } 
} 
+0

Questo ha funzionato, grazie. In aggiunta a quanto sopra, se non si mette la proprietà della colonna @Column (name = "created_date", aggiornabile = false) durante l'aggiornamento sarà nullo. – Buminda

20

Penso che si possa ottenere in almeno due modi.

valore predefinito Database

penso che il modo più semplice sarebbe quella di segnare la colonna come updateable=false, insertable=false (questo vi darà immutabilità - l'APP non includerà questa colonna in INSERT e UPDATE dichiarazioni) e l'impostazione del database colonna per avere un valore predefinito di NOW.

JPA Lifecycle metodi di callback

altro modo sarebbe quello di fornire un metodo di callback @PrePersist ciclo di vita che avrebbe impostato l'oggetto data per la data effettiva new Date(). Quindi dovresti assicurarti che nessuno modificherà questo valore, quindi non dovresti fornire alcun setter per questa proprietà.

Se si desidera aggiornare la data quando si modifica l'entità, è possibile, allo stesso modo, implementare il metodo di callback del ciclo di vita @PreUpdate che imposterà la data di modifica effettiva.

Basta ricordare che se si sta lavorando con oggetti Date si dovrebbe fare una copia difensiva del vostro oggetto Date (così si dovrebbe tornare qualcosa come new Date(oldDate.getTime()); invece del semplice return oldDate).
Ciò impedirà agli utenti di utilizzare getter del vostro Date e modificarne lo stato.

+0

Dove dovrei contrassegnare la colonna aggiornabile = falso ecc ...? Usando un'annotazione? Inoltre, perché ho bisogno di una copia difensiva sui getter? Getter non chiamerà comunque 'save() ', quindi come può cambiare il valore? – ripper234

+0

Sì, aggiungendo l'annotazione '@ Column' sul campo data (o facendo nel file' orm.xml' se lo si usa). 'Java.util.Date' è una classe mutabile. L'utente può ottenerlo usando getter, quindi ottiene un riferimento al campo Data della tua classe. Può invocare i.e. date.setTime (1) cambiando così lo stato della data. Quindi il JPA manterrà il tuo oggetto data che è stato modificato dall'utente. –

+0

JPA persisterà solo se chiami esplicitamente 'save()'. Ad ogni modo, se per "utenti" intendi "persone che sono in grado di scrivere codice Java nel mio progetto", non è un problema per me. Se intendi visitatori effettivi sul mio sito, non capisco come possano fare qualcosa per chiamare 'set' sull'oggetto data. – ripper234

Problemi correlati