Class JPAStorageService

All Implemented Interfaces:
Component, DestructableComponent, IdentifiableComponent, IdentifiedComponent, InitializableComponent, StorageCapabilities, StorageCapabilitiesEx, StorageService

public class JPAStorageService extends AbstractStorageService implements StorageCapabilitiesEx
Implementation of StorageService that uses JPA to persist to a database.
  • Field Details

    • log

      @Nonnull private final org.slf4j.Logger log
      Class logger.
    • entityManagerFactory

      @Nonnull private final javax.persistence.EntityManagerFactory entityManagerFactory
      Entity manager factory.
    • transactionRetry

      @NonNegative private int transactionRetry
      Number of times to retry a transaction if it rolls back.
  • Constructor Details

    • JPAStorageService

      public JPAStorageService(@Nonnull javax.persistence.EntityManagerFactory factory)
      Creates a new JPA storage service.
      Parameters:
      factory - entity manager factory
  • Method Details

    • getTransactionRetry

      public int getTransactionRetry()
      Returns the number of times a transaction will be retried if a RollbackException is encountered.
      Returns:
      number of transaction retries
    • setTransactionRetry

      public void setTransactionRetry(int retry)
      Sets the number of times a transaction will be retried (default is 3).
      Parameters:
      retry - number of transaction retries
    • isServerSide

      public boolean isServerSide()
      Returns true iff the storage implementation manages data independent of the client.
      Specified by:
      isServerSide in interface StorageCapabilitiesEx
      Returns:
      true iff the storage implementation manages data independent of the client
    • isClustered

      public boolean isClustered()
      Returns true iff the storage implementation manages data independent of a single server node.
      Specified by:
      isClustered in interface StorageCapabilitiesEx
      Returns:
      true iff the storage implementation manages data independent of a single server node
    • doDestroy

      protected void doDestroy()
      Overrides:
      doDestroy in class AbstractStorageService
    • create

      public boolean create(@Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key, @Nonnull @NotEmpty String value, @Nullable @Positive Long expiration) throws IOException
      Creates a new record in the store with an expiration.
      Specified by:
      create in interface StorageService
      Parameters:
      context - a storage context label
      key - a key unique to context
      value - value to store
      expiration - expiration for record, or null
      Returns:
      true iff record was inserted, false iff a duplicate was found
      Throws:
      IOException - if fatal errors occur in the insertion process
    • readAll

      @Nonnull @NonnullElements public List<?> readAll() throws IOException
      Returns all records from the store.
      Returns:
      all records or an empty list
      Throws:
      IOException - if errors occur in the read process
    • readAll

      @Nonnull @NonnullElements public List<?> readAll(@Nonnull @NotEmpty String context) throws IOException
      Returns all records from the store for the supplied context.
      Parameters:
      context - a storage context label
      Returns:
      all records in the context or an empty list
      Throws:
      IOException - if errors occur in the read process
    • readContexts

      @Nonnull @NonnullElements public List<String> readContexts() throws IOException
      Returns all contexts from the store.
      Returns:
      all contexts or an empty list
      Throws:
      IOException - if errors occur in the read process
    • read

      @Nullable public <T> StorageRecord<T> read(@Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key) throws IOException
      Returns an existing record from the store, if one exists.
      Specified by:
      read in interface StorageService
      Type Parameters:
      T - type of record
      Parameters:
      context - a storage context label
      key - a key unique to context
      Returns:
      the record read back, if present, or null
      Throws:
      IOException - if errors occur in the read process
    • read

      @Nonnull public <T> Pair<Long,StorageRecord<T>> read(@Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key, @Positive long version) throws IOException
      Returns an existing record from the store, along with its version.

      The first member of the pair returned will contain the version of the record in the store, or will be null if no record exists. The second member will contain the record read back. If null, the record either didn't exist (if the first member was also null) or the record was the same version as that supplied by the caller.

      Specified by:
      read in interface StorageService
      Type Parameters:
      T - type of record
      Parameters:
      context - a storage context label
      key - a key unique to context
      version - only return record if newer than supplied version
      Returns:
      a pair consisting of the version of the record read back, if any, and the record itself
      Throws:
      IOException - if errors occur in the read process
    • readImpl

      @Nonnull protected <T> Pair<Long,StorageRecord<T>> readImpl(@Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key, @Positive Long version) throws IOException
      Reads the record matching the supplied parameters. Returns an empty pair if the record cannot be found or is expired.
      Type Parameters:
      T - type of object
      Parameters:
      context - to search for
      key - to search for
      version - to match
      Returns:
      pair of version and storage record
      Throws:
      IOException - if errors occur in the read process
    • update

      public boolean update(@Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key, @Nonnull @NotEmpty String value, @Nullable @Positive Long expiration) throws IOException
      Updates an existing record in the store.
      Specified by:
      update in interface StorageService
      Parameters:
      context - a storage context label
      key - a key unique to context
      value - updated value
      expiration - expiration for record, or null
      Returns:
      true if the update succeeded, false if the record does not exist
      Throws:
      IOException - if errors occur in the update process
    • updateWithVersion

      @Nullable public Long updateWithVersion(@Positive long version, @Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key, @Nonnull @NotEmpty String value, @Nullable @Positive Long expiration) throws IOException, VersionMismatchException
      Updates an existing record in the store, if a version matches.
      Specified by:
      updateWithVersion in interface StorageService
      Parameters:
      version - only update if the current version matches this value
      context - a storage context label
      key - a key unique to context
      value - updated value
      expiration - expiration for record, or null
      Returns:
      the version of the record after update, null if no record exists
      Throws:
      IOException - if errors occur in the update process
      VersionMismatchException - if the record has already been updated to a newer version
    • updateExpiration

      public boolean updateExpiration(@Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key, @Nullable @Positive Long expiration) throws IOException
      Updates expiration of an existing record in the store.
      Specified by:
      updateExpiration in interface StorageService
      Parameters:
      context - a storage context label
      key - a key unique to context
      expiration - expiration for record, or null
      Returns:
      true if the update succeeded, false if the record does not exist
      Throws:
      IOException - if errors occur in the update process
    • updateImpl

      @Nullable protected Long updateImpl(@Nullable Long version, @Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key, @Nonnull @NotEmpty String value, @Nullable @Positive Long expiration) throws IOException, VersionMismatchException
      Updates the record matching the supplied parameters. Returns null if the record cannot be found or is expired.
      Parameters:
      version - to check
      context - to search for
      key - to search for
      value - to update
      expiration - to update
      Returns:
      whether the record was updated
      Throws:
      IOException - if errors occur in the update process
      VersionMismatchException - if the record found contains a version that does not match the parameter
    • deleteWithVersion

      public boolean deleteWithVersion(@Positive long version, @Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key) throws IOException, VersionMismatchException
      Deletes an existing record from the store if it currently has a specified version.
      Specified by:
      deleteWithVersion in interface StorageService
      Parameters:
      version - record version to delete
      context - a storage context label
      key - a key unique to context
      Returns:
      true iff the record existed and was deleted
      Throws:
      IOException - if errors occur in the deletion process
      VersionMismatchException - if the record has already been updated to a newer version
    • delete

      public boolean delete(@Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key) throws IOException
      Deletes an existing record from the store.
      Specified by:
      delete in interface StorageService
      Parameters:
      context - a storage context label
      key - a key unique to context
      Returns:
      true iff the record existed and was deleted
      Throws:
      IOException - if errors occur in the deletion process
    • deleteImpl

      protected boolean deleteImpl(@Nullable @Positive Long version, @Nonnull @NotEmpty String context, @Nonnull @NotEmpty String key) throws IOException, VersionMismatchException
      Deletes the record matching the supplied parameters.
      Parameters:
      version - to check
      context - to search for
      key - to search for
      Returns:
      whether the record was deleted
      Throws:
      IOException - if errors occur in the delete process
      VersionMismatchException - if the record found contains a version that does not match the parameter
    • updateContextExpiration

      public void updateContextExpiration(@Nonnull @NotEmpty String context, @Nullable @Positive Long expiration) throws IOException
      Updates the expiration time of all records in the context.
      Specified by:
      updateContextExpiration in interface StorageService
      Parameters:
      context - a storage context label
      expiration - a new expiration timestamp, or null
      Throws:
      IOException - if errors occur in the cleanup process
    • deleteContext

      public void deleteContext(@Nonnull @NotEmpty String context) throws IOException
      Forcibly removes all records in a given context along with any associated resources devoted to maintaining the context.
      Specified by:
      deleteContext in interface StorageService
      Parameters:
      context - a storage context label
      Throws:
      IOException - if errors occur in the cleanup process
    • reap

      public void reap(@Nonnull @NotEmpty String context) throws IOException
      Manually trigger a cleanup of expired records. The method MAY return without guaranteeing that cleanup has already occurred.
      Specified by:
      reap in interface StorageService
      Parameters:
      context - a storage context label
      Throws:
      IOException - if errors occur in the cleanup process
    • deleteContextImpl

      protected void deleteContextImpl(@Nonnull @NotEmpty String context, @Nonnull Long expiration) throws IOException
      Deletes every record with the supplied context. If expiration is supplied, only records with an expiration before the supplied expiration will be removed.
      Parameters:
      context - to delete
      expiration - (optional) to require for deletion
      Throws:
      IOException - if errors occur in the delete process
    • deleteImpl

      protected void deleteImpl(@Nonnull Long expiration) throws IOException
      Deletes every record with an expiration before the supplied expiration.
      Parameters:
      expiration - of records to delete
      Throws:
      IOException - if errors occur in the cleanup process
    • executeNamedQuery

      private <T> List<T> executeNamedQuery(@Nonnull javax.persistence.EntityManager manager, @Nonnull @NotEmpty String query, @Nonnull Map<String,Object> params, @Nonnull Class<T> clazz, @Nonnull javax.persistence.LockModeType lockMode) throws IOException
      Executes the supplied named query.
      Type Parameters:
      T - type of entity to return
      Parameters:
      manager - to execute the query
      query - to execute
      params - parameters for the query
      clazz - type of entity to return
      lockMode - of the transaction
      Returns:
      query results or an empty list
      Throws:
      IOException - if an error occurs executing the query
    • getCleanupTask

      @Nullable protected TimerTask getCleanupTask()
      Returns a cleanup task function to schedule for background cleanup.

      The default implementation does not supply one.

      Overrides:
      getCleanupTask in class AbstractStorageService
      Returns:
      a task object, or null
    • commitTransaction

      private void commitTransaction(@Nullable javax.persistence.EntityTransaction transaction)
      Commits the supplied transaction if EntityTransaction.isActive() and not EntityTransaction.getRollbackOnly(). Logs any exception that occurs.
      Parameters:
      transaction - to commit
    • rollbackTransaction

      private void rollbackTransaction(@Nullable javax.persistence.EntityTransaction transaction)
      Rolls back the supplied transaction if EntityTransaction.isActive(). Logs any exception that occurs.
      Parameters:
      transaction - to roll back
    • closeEntityManager

      private void closeEntityManager(@Nullable javax.persistence.EntityManager manager)
      Closes the supplied entity manager if EntityManager.isOpen(). Logs any exception that occurs.
      Parameters:
      manager - to close