All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.minijax.db.DefaultBaseEntity Maven / Gradle / Ivy

There is a newer version: 0.4.14
Show newest version
package org.minijax.db;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.Instant;
import java.util.Objects;
import java.util.UUID;

import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

import org.minijax.json.Json;
import org.minijax.util.IdUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The BaseEntity class is the abstract base class for all web primitives.
 *
 * ID's are set by the class.  ID's are *not* populated by JPA.
 *
 * For background:
 * 
    *
  • https://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma
  • *
  • http://www.onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html
  • *
*/ @MappedSuperclass @XmlAccessorType(XmlAccessType.FIELD) public abstract class DefaultBaseEntity implements BaseEntity { private static final Logger LOG = LoggerFactory.getLogger(DefaultBaseEntity.class); private static final long serialVersionUID = 1L; @Id @Column(columnDefinition = "BINARY(16)") @Convert(converter = UuidConverter.class) private UUID id; @Convert(converter = InstantConverter.class) @SuppressWarnings("squid:S3437") private Instant createdDateTime; @Convert(converter = InstantConverter.class) @SuppressWarnings("squid:S3437") private Instant updatedDateTime; @Convert(converter = InstantConverter.class) @SuppressWarnings("squid:S3437") private Instant deletedDateTime; protected DefaultBaseEntity() { id = IdUtils.create(); } /** * Returns the ID of the object. * * @return */ @Override public UUID getId() { return id; } /** * Sets the ID of the object. * * @param id */ @Override public void setId(final UUID id) { this.id = id; } /** * Returns the date/time when the object was created in the database. * * @return The created date/time. */ @Override public Instant getCreatedDateTime() { return createdDateTime; } /** * Sets the date/time when the object was created in the database. * * @param createdDateTime The created date/time. */ public void setCreatedDateTime(final Instant createdDateTime) { this.createdDateTime = createdDateTime; } /** * Returns the date/time when the object was last updated in the database. * * @return The updated date/time. */ @Override public Instant getUpdatedDateTime() { return updatedDateTime; } /** * Sets the date/time when the object was last updated in the database. * * @param updatedDateTime The updated date/time. */ public void setUpdatedDateTime(final Instant updatedDateTime) { this.updatedDateTime = updatedDateTime; } /** * Returns whether the object is deleted. * * Data is never truly deleted from the database. It is the responsibility * of all application logic to enforce the deleted flag as appropriate. * * @return True if the object is deleted. */ @Override public boolean isDeleted() { return deletedDateTime != null; } /** * Marks the entity as deleted. * * Shortcut for setDeletedDateTime(Instant.now()). * * @param deleted True if the object is deleted. */ @Override public void setDeleted(final boolean deleted) { deletedDateTime = deleted ? Instant.now() : null; } /** * Returns the date/time when the object was last deleted in the database. * * Data is never truly deleted from the database. It is the responsibility * of all application logic to enforce the deleted flag as appropriate. * * @return The deleted date/time. */ @Override public Instant getDeletedDateTime() { return deletedDateTime; } @PrePersist public void onPrePersist() { createdDateTime = Instant.now(); updatedDateTime = createdDateTime; } @PreUpdate public void onPreUpdate() { updatedDateTime = Instant.now(); } /** * Returns a hash code for this details object. * The hash code is completely based on the ID. * If a deriving class expects to mix/match several classes * within a hash table, then you should override and replace this. */ @Override public int hashCode() { return id == null ? 0 : id.hashCode(); } /** * Determines if this object equals another. * Equality is defined as same class type and same ID. */ @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!getClass().equals(obj.getClass())) { return false; } final DefaultBaseEntity other = (DefaultBaseEntity) obj; return Objects.equals(id, other.id); } public String toJson() throws IOException { return Json.getObjectMapper().writeValueAsString(this); } /** * Returns a SQL hint for super admin debugging. * * Note that this value *IS NOT* used in any database code. This is merely * to help developers quickly navigate their developer databases. * * @return A SQL hint. */ public String getSqlHint() { final String tableName = getClass().getSimpleName().toUpperCase(); final String hexId = getId().toString().replaceAll("-", ""); return "SELECT * FROM `" + tableName + "` WHERE ID=UNHEX('" + hexId + "');"; } /** * Copies all non-null properties from the other object to this object. * * @param other The other entity. */ public void copyNonNullProperties(final T other) { if (!getClass().equals(other.getClass())) { throw new IllegalArgumentException("Incorrect type (expected " + getClass() + ", actual " + other.getClass() + ")"); } Class currClass = getClass(); while (currClass != null) { for (final Field field : currClass.getDeclaredFields()) { copyNonNullField(other, field); } currClass = currClass.getSuperclass(); } } private void copyNonNullField(final T other, final Field field) { if (Modifier.isStatic(field.getModifiers())) { return; } if (field.getName().equals("id")) { return; } try { field.setAccessible(true); final Object value = field.get(other); if (value != null) { field.set(this, value); } } catch (final IllegalAccessException ex) { LOG.error(ex.getMessage(), ex); } } public static T fromJson(final Class c, final String str) throws IOException { return Json.getObjectMapper().readValue(str, c); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy