package de.flower.common.model.db.entity;
import de.flower.common.model.db.type.ObjectStatus;
import org.hibernate.annotations.Index;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.Date;
/**
* @author flowerrrr
*/
@MappedSuperclass
public abstract class AbstractBaseEntity implements Serializable, IEntity, IObjectStatusAware, Cloneable {
/**
* This constant is only needed for serialization purposes. It overwrites the default mechanism and so makes the BE longer binary compatible
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.ORDINAL)
@Column
@Index(name = "ix_objectstatus")
private ObjectStatus objectStatus;
/**
* Using default values is not so easy. See http://opensource.atlassian.com/projects/hibernate/browse/ANN-604.
*/
@Column
@Index(name = "ix_createDate")
private Date createDate = new Date();
/**
* @Version ensures that hibernate will always update the value when saving an entity.
*/
// @Version (would require to init all existing records with an value. until necessary feature is not used)
@Column
private Date updateDate;
protected AbstractBaseEntity() {
this.objectStatus = ObjectStatus.ACTIVE;
}
/**
* Gets the id.
*
* @return the id
*/
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
* Returns true if this entity is transient (not saved yet).
*
* @return true, if checks if is transient
*/
@Override
public boolean isNew() {
return (getId() == null);
}
public ObjectStatus getObjectStatus() {
return this.objectStatus;
}
public void setObjectStatus(ObjectStatus objectStatus) {
this.objectStatus = objectStatus;
}
public final boolean isActive() {
return objectStatus == ObjectStatus.ACTIVE;
}
public final boolean isDeleted() {
return objectStatus == ObjectStatus.DELETED;
}
public final boolean isFixed() {
return objectStatus == ObjectStatus.FIXED;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(final Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(final Date updateDate) {
this.updateDate = updateDate;
}
@Override
public String toString() {
return "AbstractBaseEntity@" + super.hashCode() + "{" +
"id=" + id +
'}';
}
/**
* The @Id fields are not copied.
* Reason: you cannot copy a persistent object
* with already existing primary key.
*
* @return
*/
@Override
public AbstractBaseEntity clone() {
try {
AbstractBaseEntity clone = (AbstractBaseEntity) super.clone();
clone.setId(null);
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
/**
* Update from object.
*
* @param other the other
*/
public void updateFromObject(AbstractBaseEntity other) {
throw new UnsupportedOperationException("Method must be implemented in subclass!");
}
/**
* The equality object.
*/
@Transient
private Object equalityObject;
/**
* The following methods are taken from
* http://forum.hibernate.org/viewtopic.php?p=2191778.
*
* @param other the other
* @return true, if equals
*/
@Override
public boolean equals(Object other) {
if ((this == other)) {
return true;
}
if ((other == null)) {
return false;
}
if (!(this.getClass().isInstance(other))) {
return false;
}
AbstractBaseEntity castOther = (AbstractBaseEntity) other;
if (this.getId() == null) {
return false;
}
if (castOther.getId() == null) {
return false;
}
boolean equals = ((this.getId() == castOther.getId()) || ((this.getId() != null)
&& (castOther.getId() != null) && this.getId().equals(
castOther.getId())));
return equals;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
Object o = getEqualityObject();
if (o == this) {
return super.hashCode();
} else {
return o.hashCode();
}
}
/**
* Gets the equality object.
*
* @return the equality object
*/
private Object getEqualityObject() {
if (equalityObject == null) {
equalityObject = (getId() == null) ? this : getId();
}
return equalityObject;
}
}