package org.hibernate.examples.model; import org.hibernate.examples.utils.HashTool; import org.hibernate.examples.utils.ToStringHelper; import javax.persistence.MappedSuperclass; import javax.persistence.PostLoad; import javax.persistence.PostPersist; import java.io.Serializable; /** * Hibernate Entity의 최상위 추상화 클래스입니다. * * @author 배성혁 sunghyouk.bae@gmail.com * @since 2013. 11. 27. 오후 2:36 */ @MappedSuperclass public abstract class AbstractHibernateEntity<TId extends Serializable> extends AbstractPersistentObject implements HibernateEntity<TId> { abstract public TId getId(); // NOTE: JPA 에서는 #onSave(), #onLoad() 를 @MappedSuperclass 나 @Entity 에 재정의해야한다. // NOTE: Hibernate 에서는 Interceptor에서 관리하므로, {@link AbstractPersistentObject}에만 정의해도 된다. @Override @PostPersist public final void onSave() { setPersisted(true); } @Override @PostLoad public final void onLoad() { setPersisted(true); } @Override @SuppressWarnings("unchecked") public boolean equals(Object obj) { boolean isSampeType = (obj != null) && getClass().equals(obj.getClass()); if (isSampeType) { HibernateEntity<TId> entity = (HibernateEntity<TId>) obj; return hasSameNonDefaultIdAs(entity) || ((!isPersisted() || !entity.isPersisted()) && hasSameBusinessSignature(entity)); } return false; } @Override public int hashCode() { return (getId() == null) ? System.identityHashCode(this) : HashTool.compute(getId()); } private boolean hasSameNonDefaultIdAs(HibernateEntity<TId> entity) { if (entity == null) return false; TId id = getId(); TId entityId = entity.getId(); return (id != null) && (entityId != null) && (id.equals(entityId)); } private boolean hasSameBusinessSignature(HibernateEntity<TId> other) { boolean notNull = (other != null); int hash = (getId() != null) ? HashTool.compute(getId()) : hashCode(); if (notNull) { int otherHash = (other.getId() != null) ? HashTool.compute(other.getId()) : other.hashCode(); return hash == otherHash; } return false; } @Override public ToStringHelper buildStringHelper() { return super.buildStringHelper() .add("id", getId()); } private static final long serialVersionUID = 6661386933952675946L; }