JPA – Audit

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.

Related Posts

Foto von Ruslan Ataev: https://www.pexels.com/de-de/foto/hande-frau-muster-vintage-19747303/

Elementor – Erstes Theme

Ich habe endlich mal ein Elementor Theme erstellt. Bzw. dieses Theme ist mit Elementor erzeugt worden. Eigentlich ist das ganze sehr einfach. Zuerst einmal muss

Pizza – wieder Mal

Und schon wieder gabs Pizza vom Grill. Aber ein Pizzaofen wäre schon cool. Mal sehen, ob ich mir einen zulege. Es hat wieder gut geschmeckt.

ein weinendes Schaltauge

Ja, endlich ist das neue Fahrrad von Cannondale (Gravelbike Topstone 2) da und schon zwei Wochen später schon der erste Defekt. Das Fahrrad ist umgestürzt

Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Außerdem geben wir Informationen zu Ihrer Verwendung unserer Website an unsere Partner für soziale Medien, Werbung und Analysen weiter. Unsere Partner führen diese Informationen möglicherweise mit weiteren Daten zusammen, die Sie ihnen bereitgestellt haben oder die sie im Rahmen Ihrer Nutzung der Dienste gesammelt haben. 

DatenschutzImpressum