All Classes and Interfaces
Class
Description
Strategy for when an aggregate snapshot should be added
Common interface that all concrete (classical)
Aggregate's must implement.Interface responsible for resolve the optional aggregate id associated with the type
Example of usages:
Command - return the aggregate id associated with the command (can return an
TExample of usages:
Command - return the aggregate id associated with the command (can return an
Optional.empty())
in case server generated id's are used for commands that create a new Aggregate instance)
Event - return the aggregate id associated with the event
State - return the aggregate id associated with the aggregate state event projection
View - return the aggregate id associated with the View event projection
AggregateRoot<ID,EVENT_TYPE extends Event<ID>,AGGREGATE_TYPE extends AggregateRoot<ID,EVENT_TYPE,AGGREGATE_TYPE>>
A specialized and opinionated mutable
This
This design is deliberate and will manage a lot of things for you as a developer at the cost of some flexibility.
Aggregate designThis
AggregateRoot is designed to work with Class based Event's that inherit from Event.This design is deliberate and will manage a lot of things for you as a developer at the cost of some flexibility.
A modern opinionated interpretation of the classic
The modern interpretation doesn't specify any requirement on the design of the Events, they can be Java 17+ records or simple POJO's.
Note: The
The modern
If you wish to keep the state projection and
AggregateRoot design, where the Event's are mutable.The modern interpretation doesn't specify any requirement on the design of the Events, they can be Java 17+ records or simple POJO's.
Note: The
AggregateRoot works best in combination with the StatefulAggregateRepository that's configured to use the StatefulAggregateInstanceFactory.reflectionBasedAggregateRootFactory(),
because the AggregateRoot needs to be provided its aggregated id through the AggregateRoot(Object) constructor!The modern
AggregateRoot supports keeping the state projection and EventHandler annotated methods within the AggregateRoot instance or within an AggregateState instance.If you wish to keep the state projection and
EventHandler annotated methods within an AggregateState instance, then you only need to implement the WithState interface:AggregateRootWithState<ID,EVENT_TYPE extends Event<ID>,STATE extends AggregateState<ID,EVENT_TYPE>,AGGREGATE_TYPE extends AggregateRootWithState<ID,EVENT_TYPE,STATE,AGGREGATE_TYPE>>
Variant of the
When the
AggregateRoot pattern where the aggregate's state and all EventHandler annotated methods
are placed within the concrete AggregateState object.When the
AggregateRootWithState is combined with AggregateState, then the AggregateRootWithState
will contain the command methods and the AggregateState contains the state fields and the
EventHandler annotated methods.Aggregate snapshot loaded using
loadSnapshot(AggregateType, Object, Class)Strategy for which historic aggregate snapshots (i.e.
Strategy that deletes any historic aggregate snapshots when a new snapshot is persisted
Strategy that keeps all or a specific number of historic aggregate snapshots
Repository storing and updating Aggregate instance snapshots
Base class for the state object associated with
When this is combined with the
AggregateRootWithState.When this is combined with the
AggregateRootWithState when the AggregateRootWithState
will contain the command methods and the AggregateState contains the state fields and the
EventHandler annotated methods.Aggregate state object associated with a given
Example:
AggregateRoot instance (see AggregateState.getAggregate())Example:
AggregateSnapshot.aggregateSnapshot value that's returned from AggregateSnapshotRepository in case the
Aggregate snapshot couldn't be deserializedCommand Handler which is responsible for loading any existing Aggregate
The actual logic is delegated to an instance of a
STATE from the underlying EventStore
(see CommandHandler.deciderBasedCommandHandler(ConfigurableEventStore, AggregateType, Class, AggregateIdResolver, AggregateIdResolver, AggregateSnapshotRepository, Class, Decider))
and coordinate persisting any changes to the Aggregate, in the form of EVENT's, to the EventStore as part of an active UnitOfWork (if one exists)The actual logic is delegated to an instance of a
DeciderVariant of the event sourced Decider pattern, which supports building an Aggregate
STATE based on previous EVENT's that relate to the
aggregate instance, and which can handle COMMAND's, whose side effect is either an ERROR or a List of EVENT's (can be an empty list)Delegating
This ensures that expensive update/clean-up for aggregate snapshots in the database don't affect aggregate persistence performance.
AggregateSnapshotRepository which directly delegates all operations to the provided delegateRepository,
except for aggregateUpdated(Object, AggregateEventStream), deleteSnapshots(AggregateType, Object, Class, List), which are performed asynchronously in the background.This ensures that expensive update/clean-up for aggregate snapshots in the database don't affect aggregate persistence performance.
Based Event type that's built to work in combination with
All you need to do is to inherit from this class when building your own
AggregateRootAll you need to do is to inherit from this class when building your own
Event types.Methods annotated with this Annotation will automatically be called when an event is being applied or rehydrated on to an
Aggregate instanceWrapper object that captures the results of any command handling (e.g.
Simple, easy and opinionated aggregate that allows you to apply events that don't have any requirements
with regards to inheritance (i.e.
Opinionated
FlexAggregate Repository that's built to persist and load a specific FlexAggregate type in combination
with EventStore, EventStoreUnitOfWorkFactory and a FlexAggregateRepository.FlexAggregateRepository.DefaultFlexAggregateRepository<ID,AGGREGATE_TYPE extends FlexAggregate<ID,AGGREGATE_TYPE>>
Decider related interface that is responsible for handling COMMAND(s),whose side effect is either an ERROR or a List of EVENT's (can be an empty list)Captures that result of calling a
Concrete instances can either be of type
Handler.handle(Object, Object) for a specific COMMAND and aggregate STATEConcrete instances can either be of type
HandlerResult.Success or type HandlerResult.ErrorError variant of the
HandlerResultSuccess variant of the
HandlerResultDecider or View related interface, which provides the Initial STATE for a given aggregate/projection/view.The
InitialStateProvider works in collaboration with the StateEvolver in the context of
the Decider or View patternDecider related interface that resolves if the aggregate's state is final and no more changes can occur, i.e.StatefulAggregate<ID,EVENT_TYPE,AGGREGATE_TYPE extends StatefulAggregate<ID,EVENT_TYPE,AGGREGATE_TYPE>>
Aggregate specific InMemoryProjectorNote: An in memory projection is never associated with a
UnitOfWork and any changes to the aggregate
won't automatically be persisted.Factory that helps the
StatefulAggregateRepository/StatefulAggregateInMemoryProjector to create an instance of a given Aggregate.StatefulAggregateInstanceFactory that uses Objenesis to create a new instance of the AggregatePlease note: Objenesis doesn't initialize fields nor call any constructors, so you
Aggregate design needs to take
this into consideration.All concrete aggregates that extends
AggregateRoot have been prepared to be initialized by ObjenesisStatefulAggregateInstanceFactory that calls the default no-arguments constructor on the concrete Aggregate type to
create a new instance of the AggregateStatefulAggregateRepository<ID,EVENT_TYPE,AGGREGATE_IMPL_TYPE extends StatefulAggregate<ID,EVENT_TYPE,AGGREGATE_IMPL_TYPE>>
Opinionated
You can use the
Alternatively you can extend from the
Aggregate Repository that's built to persist and load a specific StatefulAggregate type in combination
with EventStore, UnitOfWorkFactory and a StatefulAggregateInstanceFactory.You can use the
StatefulAggregateRepository.from(ConfigurableEventStore, AggregateEventStreamConfiguration, StatefulAggregateInstanceFactory, Class) to create a new StatefulAggregateRepository
instance that supports the most common repository method.Alternatively you can extend from the
StatefulAggregateRepository.DefaultStatefulAggregateRepository and add your own special methodsStatefulAggregateRepository.DefaultStatefulAggregateRepository<ID,EVENT_TYPE,AGGREGATE_IMPL_TYPE extends StatefulAggregate<ID,EVENT_TYPE,AGGREGATE_IMPL_TYPE>>
Default
StatefulAggregateRepository implementation.Variant of the Event Sourced Projection/View concept
WithState<ID,EVENT_TYPE,AGGREGATE_TYPE extends AggregateRoot<ID,EVENT_TYPE,AGGREGATE_TYPE>,AGGREGATE_STATE extends AggregateState<ID,EVENT_TYPE,AGGREGATE_TYPE>>
Marker interface that indicates that all state and all
EventHandler annotated methods
will be hosted with the AggregateState object.