T
- The type of aggregate this repository storespublic abstract class AbstractRepository<T,A extends Aggregate<T>> extends Object implements Repository<T>
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
.
LockingRepository
Modifier and Type | Class and Description |
---|---|
static class |
AbstractRepository.Builder<T>
Abstract Builder class to instantiate
AbstractRepository implementations. |
Modifier and Type | Field and Description |
---|---|
protected RepositorySpanFactory |
spanFactory |
Modifier | Constructor and Description |
---|---|
protected |
AbstractRepository(AbstractRepository.Builder<T> builder)
Instantiate a
AbstractRepository based on the fields contained in the AbstractRepository.Builder . |
Modifier and Type | Method and Description |
---|---|
protected AggregateModel<T> |
aggregateModel()
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> |
getAggregateType()
Returns the aggregate type stored by this repository.
|
A |
load(String aggregateIdentifier)
Load the aggregate with the given unique identifier.
|
A |
load(String aggregateIdentifier,
Long expectedVersion)
Load the aggregate with the given unique identifier.
|
Aggregate<T> |
loadOrCreate(String aggregateIdentifier,
Callable<T> factoryMethod)
Loads an aggregate from the repository.
|
protected Map<String,A> |
managedAggregates(UnitOfWork<?> uow)
Returns the map of aggregates currently managed by this repository under the given unit of work.
|
A |
newInstance(Callable<T> factoryMethod)
Creates a new managed instance for the aggregate, using the given
factoryMethod
to instantiate the aggregate's root. |
A |
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)
|
protected void |
validateOnLoad(Aggregate<T> aggregate,
Long expectedVersion)
Checks the aggregate for concurrent changes.
|
protected final RepositorySpanFactory spanFactory
protected AbstractRepository(AbstractRepository.Builder<T> builder)
AbstractRepository
based on the fields contained in the AbstractRepository.Builder
.
The provided Builder's main goal is to build an AggregateModel
specifying generic T
as the
aggregate type to be stored. All aggregates in this repository must be instanceOf
this aggregate type.
To instantiate this AggregateModel, either an AggregateModel
can be provided directly or an
aggregateType
of type Class
can be used. The latter will internally resolve to an
AggregateModel. Thus, either the AggregateModel or the aggregateType
should be provided. An
AxonConfigurationException
is thrown if this criteria is not met.
builder
- the AbstractRepository.Builder
used to instantiate a AbstractRepository
instancepublic A newInstance(@Nonnull Callable<T> factoryMethod) throws Exception
Repository
factoryMethod
to instantiate the aggregate's root.newInstance
in interface Repository<T>
factoryMethod
- The method to create the aggregate's root instanceException
- when the factoryMethod throws an exceptionpublic A newInstance(@Nonnull Callable<T> factoryMethod, @Nonnull Consumer<Aggregate<T>> initMethod) throws Exception
Repository
factoryMethod
to instantiate the
aggregate's root, and then applying the initMethod
consumer to it to perform additional
initialization.newInstance
in interface Repository<T>
factoryMethod
- The method to create the aggregate's root instanceinitMethod
- The consumer to initialize the aggregate instance furtherException
- when the factoryMethod throws an exceptionprotected abstract A doCreateNew(Callable<T> factoryMethod) throws Exception
factoryMethod
. Implementations should assume that this
method is only called if a UnitOfWork is currently active.factoryMethod
- The method to create the aggregate's root instanceException
- when the factoryMethod throws an exceptionpublic A load(@Nonnull String aggregateIdentifier, Long expectedVersion)
Repository
load
in interface Repository<T>
aggregateIdentifier
- The identifier of the aggregate to loadexpectedVersion
- The expected version of the loaded aggregateAggregateNotFoundException
- if aggregate with given id cannot be foundRuntimeException
- any exception thrown by implementing classespublic Aggregate<T> loadOrCreate(@Nonnull String aggregateIdentifier, @Nonnull Callable<T> factoryMethod)
Repository
factoryMethod
.loadOrCreate
in interface Repository<T>
aggregateIdentifier
- The identifier of the aggregate to loadfactoryMethod
- The method to create the aggregate's root instanceprotected Map<String,A> managedAggregates(UnitOfWork<?> uow)
The returns map is mutable and reflects any changes made during processing.
uow
- The unit of work to find the managed aggregates forpublic A load(@Nonnull String aggregateIdentifier)
Repository
load
in interface Repository<T>
aggregateIdentifier
- The identifier of the aggregate to loadprotected void validateOnLoad(Aggregate<T> aggregate, Long expectedVersion)
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
aggregate
- The loaded aggregateexpectedVersion
- The expected version of the aggregateConflictingModificationException
- when conflicting changes have been detectedConflictingAggregateVersionException
- the expected version is not null
and the version number of the aggregate does not match the expected
versionprotected void prepareForCommit(A aggregate)
aggregate
when
the Unit of Work is committed.aggregate
- The Aggregate to save or delete when the Unit of Work is committedprotected void reportIllegalState(A aggregate)
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.
aggregate
- The aggregate instance with illegal stateprotected AggregateModel<T> aggregateModel()
protected Class<? extends T> getAggregateType()
protected abstract void doSave(A aggregate)
aggregate
- the aggregate to storeprotected abstract A doLoad(String aggregateIdentifier, Long expectedVersion)
aggregateIdentifier
- the identifier of the aggregate to loadexpectedVersion
- The expected version of the aggregate to loadAggregateNotFoundException
- if the aggregate with given identifier does not existprotected A doLoadOrCreate(String aggregateIdentifier, Callable<T> factoryMethod) throws Exception
factoryMethod
.aggregateIdentifier
- the identifier of the aggregatefactoryMethod
- the method that creates a new instanceException
- when loading or creating the aggregate failedprotected abstract void doDelete(A aggregate)
doLoad(String, Long)
throw a AggregateNotFoundException
when
loading a deleted aggregate.aggregate
- the aggregate to deleteprotected void postSave(A aggregate)
aggregate
- The aggregate instance being savedprotected void postDelete(A aggregate)
aggregate
- The aggregate instance being savedpublic void send(@Nonnull Message<?> message, @Nonnull ScopeDescriptor scopeDescription) throws Exception
ScopeAware
send
in interface ScopeAware
message
- a Message
to be send to a Scope
scopeDescription
- a D
extending ScopeDescriptor
, describing the Scope
to send the
given message
toException
- if sending the message
failed. Might occur if the message handling process throws an
exceptionpublic boolean canResolve(@Nonnull ScopeDescriptor scopeDescription)
ScopeAware
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.canResolve
in interface ScopeAware
scopeDescription
- a ScopeDescriptor
describing the Scope
to be resolvedtrue
in case it should be able to resolve the Scope and false
if it cannotCopyright © 2010–2024. All rights reserved.