Class AbstractRepository<T,A extends Aggregate<T>>

java.lang.Object
org.axonframework.modelling.command.AbstractRepository<T,A>
Type Parameters:
T - The type of aggregate this repository stores
All Implemented Interfaces:
ScopeAware, Repository<T>
Direct Known Subclasses:
LockingRepository

public abstract class AbstractRepository<T,A extends Aggregate<T>> extends Object implements Repository<T>
Abstract implementation of the Repository that takes care of the dispatching of events when an aggregate is persisted. All uncommitted events on an aggregate are dispatched when the aggregate is saved.

Note that this repository implementation does not take care of any locking. The underlying persistence is expected to deal with concurrency. Alternatively, consider using the LockingRepository.

Since:
0.1
Author:
Allard Buijze
See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 
    Abstract Builder class to instantiate AbstractRepository implementations.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected final RepositorySpanFactory
     
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    Instantiate a AbstractRepository based on the fields contained in the AbstractRepository.Builder.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected AggregateModel<T>
    Returns the aggregate model stored by this repository.
    boolean
    canResolve(ScopeDescriptor scopeDescription)
    Check whether this implementation can resolve a Scope object based on the provided scopeDescription.
    protected abstract A
    doCreateNew(Callable<T> factoryMethod)
    Creates a new aggregate instance using the given factoryMethod.
    protected abstract void
    doDelete(A aggregate)
    Removes the aggregate from the repository.
    protected abstract A
    doLoad(String aggregateIdentifier, Long expectedVersion)
    Loads and initialized the aggregate with the given aggregateIdentifier.
    protected A
    doLoadOrCreate(String aggregateIdentifier, Callable<T> factoryMethod)
    Loads an aggregate from the reporsitory.
    protected abstract void
    doSave(A aggregate)
    Performs the actual saving of the aggregate.
    protected Class<? extends T>
    Returns the aggregate type stored by this repository.
    load(String aggregateIdentifier)
    Load the aggregate with the given unique identifier.
    load(String aggregateIdentifier, Long expectedVersion)
    Load the aggregate with the given unique identifier.
    loadOrCreate(String aggregateIdentifier, Callable<T> factoryMethod)
    Loads an aggregate from the repository.
    protected Map<String,A>
    Returns the map of aggregates currently managed by this repository under the given unit of work.
    newInstance(Callable<T> factoryMethod)
    Creates a new managed instance for the aggregate, using the given factoryMethod to instantiate the aggregate's root.
    newInstance(Callable<T> factoryMethod, Consumer<Aggregate<T>> initMethod)
    Creates a new managed instance for the aggregate, using the given factoryMethod to instantiate the aggregate's root, and then applying the initMethod consumer to it to perform additional initialization.
    protected void
    postDelete(A aggregate)
    Perform action that needs to be done directly after deleting an aggregate and committing the aggregate's uncommitted events.
    protected void
    postSave(A aggregate)
    Perform action that needs to be done directly after updating an aggregate and committing the aggregate's uncommitted events.
    protected void
    prepareForCommit(A aggregate)
    Register handlers with the current Unit of Work that save or delete the given aggregate when the Unit of Work is committed.
    protected void
    reportIllegalState(A aggregate)
    Invoked when an the given aggregate instance has been detected that has been part of a rolled back Unit of Work.
    void
    send(Message<?> message, ScopeDescriptor scopeDescription)
    Send a Message to a Scope which is described by the given scopeDescription.
    protected void
    validateOnLoad(Aggregate<T> aggregate, Long expectedVersion)
    Checks the aggregate for concurrent changes.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

  • Method Details

    • newInstance

      public A newInstance(@Nonnull Callable<T> factoryMethod) throws Exception
      Description copied from interface: Repository
      Creates a new managed instance for the aggregate, using the given factoryMethod to instantiate the aggregate's root.
      Specified by:
      newInstance in interface Repository<T>
      Parameters:
      factoryMethod - The method to create the aggregate's root instance
      Returns:
      an Aggregate instance describing the aggregate's state
      Throws:
      Exception - when the factoryMethod throws an exception
    • newInstance

      public A newInstance(@Nonnull Callable<T> factoryMethod, @Nonnull Consumer<Aggregate<T>> initMethod) throws Exception
      Description copied from interface: Repository
      Creates a new managed instance for the aggregate, using the given factoryMethod to instantiate the aggregate's root, and then applying the initMethod consumer to it to perform additional initialization.
      Specified by:
      newInstance in interface Repository<T>
      Parameters:
      factoryMethod - The method to create the aggregate's root instance
      initMethod - The consumer to initialize the aggregate instance further
      Returns:
      an Aggregate instance describing the aggregate's state
      Throws:
      Exception - when the factoryMethod throws an exception
    • doCreateNew

      protected abstract A doCreateNew(Callable<T> factoryMethod) throws Exception
      Creates a new aggregate instance using the given factoryMethod. Implementations should assume that this method is only called if a UnitOfWork is currently active.
      Parameters:
      factoryMethod - The method to create the aggregate's root instance
      Returns:
      an Aggregate instance describing the aggregate's state
      Throws:
      Exception - when the factoryMethod throws an exception
    • load

      public A load(@Nonnull String aggregateIdentifier, Long expectedVersion)
      Description copied from interface: Repository
      Load the aggregate with the given unique identifier.
      Specified by:
      load in interface Repository<T>
      Parameters:
      aggregateIdentifier - The identifier of the aggregate to load
      expectedVersion - The expected version of the loaded aggregate
      Returns:
      The aggregate root with the given identifier.
      Throws:
      AggregateNotFoundException - if aggregate with given id cannot be found
      RuntimeException - any exception thrown by implementing classes
    • loadOrCreate

      public Aggregate<T> loadOrCreate(@Nonnull String aggregateIdentifier, @Nonnull Callable<T> factoryMethod)
      Description copied from interface: Repository
      Loads an aggregate from the repository. If the aggregate is not found it creates the aggregate using the specified factoryMethod.
      Specified by:
      loadOrCreate in interface Repository<T>
      Parameters:
      aggregateIdentifier - The identifier of the aggregate to load
      factoryMethod - The method to create the aggregate's root instance
      Returns:
      The aggregate root with the given identifier.
    • managedAggregates

      protected Map<String,A> managedAggregates(UnitOfWork<?> uow)
      Returns the map of aggregates currently managed by this repository under the given unit of work. Note that the repository keeps the managed aggregates in the root unit of work, to guarantee each Unit of Work works with the state left by the parent unit of work.

      The returns map is mutable and reflects any changes made during processing.

      Parameters:
      uow - The unit of work to find the managed aggregates for
      Returns:
      a map with the aggregates managed by this repository in the given unit of work
    • load

      public A load(@Nonnull String aggregateIdentifier)
      Description copied from interface: Repository
      Load the aggregate with the given unique identifier. No version checks are done when loading an aggregate, meaning that concurrent access will not be checked for.
      Specified by:
      load in interface Repository<T>
      Parameters:
      aggregateIdentifier - The identifier of the aggregate to load
      Returns:
      The aggregate root with the given identifier.
    • validateOnLoad

      protected void validateOnLoad(Aggregate<T> aggregate, Long expectedVersion)
      Checks the aggregate for concurrent changes. Throws a ConflictingModificationException when conflicting changes have been detected.

      This implementation throws a ConflictingAggregateVersionException if the expected version is not null and the version number of the aggregate does not match the expected version

      Parameters:
      aggregate - The loaded aggregate
      expectedVersion - The expected version of the aggregate
      Throws:
      ConflictingModificationException - when conflicting changes have been detected
      ConflictingAggregateVersionException - the expected version is not null and the version number of the aggregate does not match the expected version
    • prepareForCommit

      protected void prepareForCommit(A aggregate)
      Register handlers with the current Unit of Work that save or delete the given aggregate when the Unit of Work is committed.
      Parameters:
      aggregate - The Aggregate to save or delete when the Unit of Work is committed
    • reportIllegalState

      protected void reportIllegalState(A aggregate)
      Invoked when an the given aggregate instance has been detected that has been part of a rolled back Unit of Work. This typically means that the state of the Aggregate instance has been compromised and cannot be guaranteed to be correct.

      This implementation throws an exception, effectively causing the unit of work to be rolled back. Subclasses that can guarantee correct storage, even when specific instances are compromised, may override this method to suppress this exception.

      When this method is invoked, the doSave(Aggregate), doDelete(Aggregate), postSave(Aggregate) and postDelete(Aggregate) are not invoked. Implementations may choose to invoke these methods.

      Parameters:
      aggregate - The aggregate instance with illegal state
    • aggregateModel

      protected AggregateModel<T> aggregateModel()
      Returns the aggregate model stored by this repository.
      Returns:
      the aggregate model stored by this repository
    • getAggregateType

      protected Class<? extends T> getAggregateType()
      Returns the aggregate type stored by this repository.
      Returns:
      the aggregate type stored by this repository
    • doSave

      protected abstract void doSave(A aggregate)
      Performs the actual saving of the aggregate.
      Parameters:
      aggregate - the aggregate to store
    • doLoad

      protected abstract A doLoad(String aggregateIdentifier, Long expectedVersion)
      Loads and initialized the aggregate with the given aggregateIdentifier.
      Parameters:
      aggregateIdentifier - the identifier of the aggregate to load
      expectedVersion - The expected version of the aggregate to load
      Returns:
      a fully initialized aggregate
      Throws:
      AggregateNotFoundException - if the aggregate with given identifier does not exist
    • doLoadOrCreate

      protected A doLoadOrCreate(String aggregateIdentifier, Callable<T> factoryMethod) throws Exception
      Loads an aggregate from the reporsitory. If the aggregate does not exists, it is created using the factoryMethod.
      Parameters:
      aggregateIdentifier - the identifier of the aggregate
      factoryMethod - the method that creates a new instance
      Returns:
      the aggregate
      Throws:
      Exception - when loading or creating the aggregate failed
    • doDelete

      protected abstract void doDelete(A aggregate)
      Removes the aggregate from the repository. Typically, the repository should ensure that any calls to doLoad(String, Long) throw a AggregateNotFoundException when loading a deleted aggregate.
      Parameters:
      aggregate - the aggregate to delete
    • postSave

      protected void postSave(A aggregate)
      Perform action that needs to be done directly after updating an aggregate and committing the aggregate's uncommitted events. No op by default.
      Parameters:
      aggregate - The aggregate instance being saved
    • postDelete

      protected void postDelete(A aggregate)
      Perform action that needs to be done directly after deleting an aggregate and committing the aggregate's uncommitted events. No op by default.
      Parameters:
      aggregate - The aggregate instance being saved
    • send

      public void send(@Nonnull Message<?> message, @Nonnull ScopeDescriptor scopeDescription) throws Exception
      Description copied from interface: ScopeAware
      Send a Message to a Scope which is described by the given scopeDescription.
      Specified by:
      send in interface ScopeAware
      Parameters:
      message - a Message to be send to a Scope
      scopeDescription - a D extending ScopeDescriptor, describing the Scope to send the given message to
      Throws:
      Exception - if sending the message failed. Might occur if the message handling process throws an exception
    • canResolve

      public boolean canResolve(@Nonnull ScopeDescriptor scopeDescription)
      Description copied from interface: ScopeAware
      Check whether this implementation can resolve a Scope object based on the provided scopeDescription. Will return true in case it should be able to resolve the Scope and false if it cannot.
      Specified by:
      canResolve in interface ScopeAware
      Parameters:
      scopeDescription - a ScopeDescriptor describing the Scope to be resolved
      Returns:
      true in case it should be able to resolve the Scope and false if it cannot