Class AuditableDataEntity<ID extends Serializable>

java.lang.Object
com.ultikits.ultitools.abstracts.data.BaseDataEntity<ID>
com.ultikits.ultitools.abstracts.data.AuditableDataEntity<ID>
Type Parameters:
ID - the type of the entity identifier
All Implemented Interfaces:
Serializable

public abstract class AuditableDataEntity<ID extends Serializable> extends BaseDataEntity<ID>
Data entity with audit fields for tracking creation and modification. Automatically manages audit timestamps and user information.
Since:
6.2.0
Version:
2.0.0
Author:
wisdomme
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      See Also:
    • createdAt

      private LocalDateTime createdAt
    • updatedAt

      private LocalDateTime updatedAt
    • createdBy

      private UUID createdBy
    • updatedBy

      private UUID updatedBy
    • CURRENT_USER

      private static final ThreadLocal<UUID> CURRENT_USER
      Sets the current user context for audit purposes. Thread-local storage for the current operation's user.
  • Constructor Details

    • AuditableDataEntity

      public AuditableDataEntity()
  • Method Details

    • setCurrentUser

      public static void setCurrentUser(UUID userId)
      Sets the current user for audit tracking. Call this before performing data operations.

      BaseCommandExecutor sets the command sender's UUID around the body that actually invokes a command's matched method, when the resolved sender is a Player -- through swapCurrentUser(UUID) as of 6.3.0, which also restores the previous user afterwards -- so a command handler's data operations record that player's UUID in createdBy/updatedBy. Nothing else in the framework sets it: a module performing data operations from outside a command handler (a scheduled task, a listener, an external plugin via the External Plugin API) is responsible for setting the context itself, or its writes record null actors.

      Parameters:
      userId - the current user's UUID
    • clearCurrentUser

      public static void clearCurrentUser()
      Clears the current user context. Call this after completing data operations.

      This removes the ThreadLocal entry entirely rather than leaving a null mapping behind, which matters on a pooled Bukkit worker thread that gets reused for a later, unrelated command. BaseCommandExecutor no longer calls it after a command body (as of 6.3.0, #541): it restores the user that was current before the body through swapCurrentUser(UUID), which removes the entry the same way when there was none.

    • swapCurrentUser

      @Internal public static UUID swapCurrentUser(UUID userId)
      Replaces the current user and returns the one it replaces, so a caller can put it back.

      BaseCommandExecutor calls this around every command body (as of 6.3.0, #541): once with the sender's UUID (or null for a sender that is not a player) before the body, and once with the returned value in a finally after it. A command body runs at dispatch on the server thread, so a body that dispatches another command runs the nested body on the same thread before its own has finished; saving and restoring keeps each body's own user, and a thread that carried no user before the outermost command carries none after it. A null argument removes the ThreadLocal entry, as clearCurrentUser() does, rather than storing null.

      Parameters:
      userId - the user to make current, or null for none
      Returns:
      the user that was current before, or null if there was none
      Since:
      6.3.0
    • getCurrentUser

      protected static UUID getCurrentUser()
      Gets the current user from the thread-local context.
      Returns:
      the current user's UUID, or null if not set
    • onCreate

      public void onCreate()
      Sets createdAt/updatedAt to now and, if a current user is set, createdBy/updatedBy to it.

      As of 6.3.0 (02-08), every relational and JSON data operator in this framework actually calls this before an entity is inserted -- previously it was reachable only by calling it directly, which nothing in the framework did, so createdAt/createdBy stayed null on every persisted row regardless of this method's own correctness. A later onUpdate() does not touch createdAt/createdBy, so the values this method writes on insert persist unchanged through every subsequent update.

      Overrides:
      onCreate in class BaseDataEntity<ID extends Serializable>
    • onUpdate

      public void onUpdate()
      Sets updatedAt to now and, if a current user is set, updatedBy to it. Deliberately does not touch createdAt/createdBy -- see onCreate().

      As of 6.3.0 (02-08), every relational and JSON data operator in this framework actually calls this before an entity is updated; see onCreate()'s note on why that was not previously true.

      Overrides:
      onUpdate in class BaseDataEntity<ID extends Serializable>
    • getAge

      public Duration getAge()
      Gets the age of this entity since creation.
      Returns:
      the duration since creation, or null if not persisted
    • getTimeSinceUpdate

      public Duration getTimeSinceUpdate()
      Gets the time since the last modification.
      Returns:
      the duration since last update, or null if not persisted
    • wasModified

      public boolean wasModified()
      Checks if this entity was modified after creation.
      Returns:
      true if modified after creation