Skip to content

Instantly share code, notes, and snippets.

@Syquel
Created June 16, 2020 18:05
Show Gist options
  • Save Syquel/199dd7921bb562ad84ae3664eeb85e0f to your computer and use it in GitHub Desktop.
Save Syquel/199dd7921bb562ad84ae3664eeb85e0f to your computer and use it in GitHub Desktop.
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