Created
June 16, 2020 18:05
-
-
Save Syquel/199dd7921bb562ad84ae3664eeb85e0f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.syquel.core.entity; | |
import java.io.Serializable; | |
import java.util.Objects; | |
import javax.persistence.Access; | |
import javax.persistence.AccessType; | |
import javax.persistence.GeneratedValue; | |
import javax.persistence.Id; | |
import javax.persistence.MappedSuperclass; | |
import javax.persistence.Transient; | |
import javax.persistence.Version; | |
import javax.validation.constraints.NotNull; | |
import org.springframework.data.domain.Persistable; | |
/** | |
* Base class for JPA entities with opinionated defaults for identity and optimistic locking. | |
* <p> | |
* Concrete JPA entities <b>SHOULD</b> extend this base class. | |
* <p> | |
* Guidelines for concrete JPA entities and abstract specializations, which extend this base class: | |
* <ul> | |
* <li>General | |
* <ul> | |
* <li>Subclasses, its properties and methods <b>MUST NOT</b> be <code>final</code>.</li> | |
* <li>Concrete JPA entity classes <b>MUST</b> be annotated with {@link javax.persistence.Entity}</li> | |
* <li>Abstract specialization classes <b>MUST</b> be <code>abstract</code> and annotated with {@link MappedSuperclass}</li> | |
* </ul> | |
* </li> | |
* <li>Properties of subclasses | |
* <ul> | |
* <li><b>MUST</b> be <code>private</code>.</li> | |
* <li><b>MUST</b> be categorized as either <b>mandatory</b> or <b>optional</b> and either <b>mutable</b> or <b>immutable</b>.</li> | |
* <li> | |
* <b>Mandatory</b> properties <b>MUST</b> be annotated with {@link javax.validation.constraints.NotNull} or | |
* a more specific validating annotation like {@link javax.validation.constraints.NotEmpty}. | |
* </li> | |
* </ul> | |
* </li> | |
* <li>Constructors of subclasses | |
* <ul> | |
* <li> | |
* Subclasses <b>MUST</b> define a default constructor without parameters.<p> | |
* If <b>mandatory</b> properties exist is <b>MUST</b> be <code>protected</code>, otherwise <code>public</code>. | |
* </li> | |
* <li> | |
* Subclasses <b>MUST</b> define a <code>public</code> constructor with all its own and its super-classes (excluding {@link AbstractEntity}) | |
* <b>mandatory</b> properties. | |
* </li> | |
* <li> | |
* Subclasses <b>MUST</b> define a <code>public</code> constructor with all its own and its super-classes (including {@link AbstractEntity}) | |
* <b>mandatory</b> properties. | |
* </li> | |
* <li>Subclasses <b>MUST NOT</b> define any further constructors.</li> | |
* </ul> | |
* </li> | |
* <li>Getters / Setters | |
* <ul> | |
* <li>Getters <b>MUST</b> be <code>public</code>.</li> | |
* <li>Setters for <b>immutable</b> properties <b>MUST</b> be <code>protected</code>.</li> | |
* <li>Setters for <b>mutable</b> properties <b>MUST</b> be <code>public</code>.</li> | |
* </ul> | |
* </li> | |
* </ul> | |
* | |
* @param <ID> the type of the JPA entity identifier. | |
* | |
* @see <a href="https://www.ietf.org/rfc/rfc2119.txt">RFC 2119 - Key words for use in RFCs to Indicate Requirement Levels</a> | |
*/ | |
@MappedSuperclass | |
@Access(AccessType.FIELD) | |
public abstract class AbstractEntity<ID extends Serializable> implements Persistable<ID>, Serializable { | |
private static final long serialVersionUID = 2786660031611103039L; | |
@Id | |
@GeneratedValue | |
@Access(AccessType.PROPERTY) | |
private ID id; | |
@Version | |
private Long version; | |
protected AbstractEntity() { | |
// Default JPA constructor | |
} | |
public AbstractEntity(@NotNull final ID id, @NotNull final Long version) { | |
this.id = id; | |
this.version = version; | |
} | |
@Override | |
public ID getId() { | |
return id; | |
} | |
protected void setId(final ID id) { | |
this.id = id; | |
} | |
public Long getVersion() { | |
return version; | |
} | |
protected void setVersion(final Long version) { | |
this.version = version; | |
} | |
@Override | |
@Transient | |
public boolean isNew() { | |
return id == null; | |
} | |
@Override | |
public boolean equals(final Object o) { | |
if (this == o) { | |
return true; | |
} | |
if (!(o instanceof AbstractEntity)) { | |
return false; | |
} | |
final AbstractEntity<?> that = (AbstractEntity<?>) o; | |
return id != null && id.equals(that.id); | |
} | |
@Override | |
public int hashCode() { | |
return Objects.hash(id); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment