/*******************************************************************************
* Copyright (c) 2015 Development Gateway, Inc and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the MIT License (MIT)
* which accompanies this distribution, and is available at
* https://opensource.org/licenses/MIT
*
* Contributors:
* Development Gateway - initial API and implementation
*******************************************************************************/
package org.devgateway.toolkit.persistence.dao;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import javax.persistence.PreUpdate;
import org.hibernate.annotations.Type;
import org.hibernate.envers.Audited;
import org.joda.time.DateTime;
import org.springframework.data.domain.Auditable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
*
* @author mpostelnicu
*
*/
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditableEntity extends GenericPersistable implements Auditable<String, Long> {
/**
*
*/
private static final long serialVersionUID = 4031407178647451427L;
@Audited
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime lastUpdated;
@Audited
private String lastModifiedBy;
@Audited
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime created;
@Audited
private String createdBy;
/**
* Forces the envers to see this object as modified, thus enabling creation
* of a revision record. This is invoked by children entities, if the entity
* has OneToMany relationships
*
* @see AbstractAuditableEntity#ensureParentUpdated()
*/
public void touch() {
setLastModifiedDate(new DateTime());
// force update of all parents, because PreUpdate does not always get
// invoked if there is nothing to update
if (getParent() != null) {
getParent().touch();
}
}
/**
* Override this in subclasses and return the parent entity, or null if no
* parent entity exists
*
* @return
*/
public abstract AbstractAuditableEntity getParent();
/**
* @see http ://stackoverflow.com/questions/10697945/hibernate-envers-track-
* revisions -in-the-owning-side-of-a-onetomany-relation updates parent
* timestamp when child is updated. Useful for forcing envers to
* generate a revision for parents when it generates a revision for
* children
*/
@PreUpdate
public void ensureParentUpdated() {
if (getParent() != null) {
getParent().touch();
}
}
/**
* Gets created by audit user.
*/
@Override
public String getCreatedBy() {
return createdBy;
}
/**
* Sets created by audit user.
*/
@Override
public void setCreatedBy(final String createdBy) {
this.createdBy = createdBy;
}
/**
* Gets create audit date.
*/
@Override
public DateTime getCreatedDate() {
return created;
}
/**
* Sets create audit date.
*/
@Override
public void setCreatedDate(final DateTime creationDate) {
this.created = creationDate;
}
/**
* Gets last modified by audit user.
*/
@Override
public String getLastModifiedBy() {
return lastModifiedBy;
}
/**
* Sets last modified by audit user.
*/
@Override
public void setLastModifiedBy(final String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
/**
* Gets last modified audit date.
*/
@Override
public DateTime getLastModifiedDate() {
return lastUpdated;
}
/**
* Sets last modified audit date.
*/
@Override
public void setLastModifiedDate(final DateTime lastModifiedDate) {
this.lastUpdated = lastModifiedDate;
}
}