/**
* Copyright 2010 CosmoCode GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.cosmocode.palava.model.base;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
/**
* Abstract base implementation of the {@link EntityBase} interface.
*
* <p>
* This implementation provides equals/hashCode-methods which
* use the return value of {@link EntityBase#getId()} for equality checks.
* </p>
*
* <p>
* The {@link AbstractEntity} class is annotated with the {@link MappedSuperclass}
* annotation and serves as a base implementation for all concrete entities.
* </p>
*
* <p>
* The fields of this implementation are all private to support proper encapsulation.
* All accessor-methods (getter/setter) are non-final an can be overriden by sub-classes.
* The setter-methods in this implementation do not validate or modify the given
* inputs.
* </p>
*
* <p>
* This implementation provides a meaningful toString-method which includes
* the simple class name, the identifier and the current version.
* </p>
*
* <p>
* The {@link EntityBase#setCreated()} and {@link EntityBase#setModified()} are annotated
* with the {@link PrePersist}- and {@link PreUpdate}-annotation.
* </p>
*
* @author Willi Schoenborn
*/
@MappedSuperclass
public abstract class AbstractEntity implements EntityBase {
@Version
private int version;
@Column(name = "created_at", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@Column(name = "modified_at")
@Temporal(TemporalType.TIMESTAMP)
private Date modifiedAt;
@Column(name = "deleted_at")
@Temporal(TemporalType.TIMESTAMP)
private Date deletedAt;
@Override
public Date getCreatedAt() {
return createdAt;
}
@Override
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
@Override
@PrePersist
public void setCreated() {
setCreatedAt(new Date());
}
@Override
public Date getModifiedAt() {
return modifiedAt;
}
@Override
public void setModifiedAt(Date modifiedAt) {
this.modifiedAt = modifiedAt;
}
@Override
@PreUpdate
public void setModified() {
setModifiedAt(new Date());
}
@Override
public Date getDeletedAt() {
return deletedAt;
}
@Override
public void setDeletedAt(Date deletedAt) {
this.deletedAt = deletedAt;
}
@Override
public void setDeleted() {
setDeletedAt(new Date());
}
@Override
public boolean isDeleted() {
return getDeletedAt() != null;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (getId() ^ (getId() >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof EntityBase)) {
return false;
}
final EntityBase other = (EntityBase) obj;
if (getId() != other.getId()) {
return false;
}
return true;
}
/**
* <p>
* This implementation produces a string containing <strong>the simple class name of this entity,
* it's identifier and the current version</strong>.
* </p>
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("%s [id=%s, version=%s]", getClass().getSimpleName(), getId(), version);
}
}