In vielen Applikationen ist es üblich, dass Zusatz-Informationen zu einem persistierten Objekt gespeichert werden. Solche Zusatzinformationen sind normalerweise: Datum und Zeit des Creates oder Updates und die User, die diese Aktionen gemacht haben. Anstatt in den Service-Klassen dauernd diese Attribute zu setzen gibt es in JPA eine elegante Möglichkeit das zu erreichen.
Die zu persistierenden Objekte sollten alle von einer Basisklasse abgeleitet sein. Diese Basisklasse besitzt nun die Attribute createdBy, createdAt, changedBy und changedAt. Mit den Annotations @PrePersist und @PreUpdate kann man Methoden kennzeichnen, die vor dem Anlegen bzw. updaten des Objekts in der Datenbank aufgerufen werden. Dort kann man die Zusatzinformationen setzen bzw. updaten.
Hier mal ein kleines Codebeispiel dazu.
/** * */ package com.nikirocks.common.domain; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.MappedSuperclass; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import org.apache.log4j.Logger; /** * @author Niki * */ @MappedSuperclass public abstract class ABase implements Serializable { private static final Logger LOG = Logger.getLogger(ABase.class); /** * */ private static final long serialVersionUID = -8317834487523332409L; protected String changedBy = "test"; protected Date created; protected String createdBy = "test"; protected Long id; protected Date lastChanged; @PrePersist public void fillCreated() { LOG.info("fillCreated called"); Date now = new Date(); this.created = now; this.lastChanged = now; } @PreUpdate public void fillLastChanged() { LOG.info("fillLastChanged called"); this.lastChanged = new Date(); } /** * @return the changedBy */ @Column(name = "changedBy", nullable = false) public String getChangedBy() { return changedBy; } /** * @return the created */ @Column(name = "created", nullable = false) public Date getCreated() { return (Date) created.clone(); } /** * @param id * the id to set */ public void setId(Long id) { this.id = id; } /** * @return the createdBy */ @Column(name = "createdBy", nullable = false) public String getCreatedBy() { return createdBy; } /** * @return the lastChanged */ @Column(name = "lastChanged", nullable = false) public Date getLastChanged() { return (Date) lastChanged.clone(); } /** * @param changedBy * the changedBy to set */ public void setChangedBy(String changedBy) { this.changedBy = changedBy; } /** * @param created * the created to set */ public void setCreated(Date created) { this.created = (Date) created.clone(); } /** * @param createdBy * the createdBy to set */ public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } /** * @param lastChanged * the lastChanged to set */ public void setLastChanged(Date lastChanged) { this.lastChanged = (Date) lastChanged.clone(); } @Override public String toString() { return "Id=" + id + ", created=" + createdBy + "@" + created + ", modified=" + lastChanged + "@" + changedBy; } }
Das einzige was man nun tun muss ist die Attribute changedBy und createdBy zu versorgen. Woher man diese Information zum aktuell eingeloggten User bekommt hängt stark von der Applikation bzw des gewählten Frameworks ab.