org.axonframework.eventsourcing
Class EventSourcingRepository<T extends EventSourcedAggregateRoot>

java.lang.Object
  extended by org.axonframework.repository.AbstractRepository<T>
      extended by org.axonframework.repository.LockingRepository<T>
          extended by org.axonframework.eventsourcing.EventSourcingRepository<T>
Type Parameters:
T - The type of aggregate this repository stores
All Implemented Interfaces:
AggregateFactory<T>, Repository<T>
Direct Known Subclasses:
CachingEventSourcingRepository, GenericEventSourcingRepository, SpringPrototypeEventSourcingRepository

public abstract class EventSourcingRepository<T extends EventSourcedAggregateRoot>
extends LockingRepository<T>
implements AggregateFactory<T>

Abstract repository implementation that allows easy implementation of an Event Sourcing mechanism. It will automatically publish new events to the given EventBus and delegate event storage to the provided EventStore.

Since:
0.1
Author:
Allard Buijze
See Also:
EventSourcedAggregateRoot, AbstractEventSourcedAggregateRoot, AbstractAnnotatedAggregateRoot, EventStore, FileSystemEventStore

Constructor Summary
protected EventSourcingRepository()
          Initializes a repository with the default locking strategy.
protected EventSourcingRepository(LockingStrategy lockingStrategy)
          Initialize a repository with the given locking strategy.
 
Method Summary
 T createAggregate(AggregateIdentifier aggregateIdentifier, DomainEvent firstEvent)
          Instantiate the aggregate using the given aggregate identifier and first event.
protected  T doLoad(AggregateIdentifier aggregateIdentifier, Long expectedVersion)
          Perform the actual loading of an aggregate.
protected  void doSaveWithLock(T aggregate)
          Perform the actual saving of the aggregate.
protected abstract  T instantiateAggregate(AggregateIdentifier aggregateIdentifier, DomainEvent firstEvent)
          Instantiate the aggregate using the given aggregate identifier and first event.
 void setConflictResolver(ConflictResolver conflictResolver)
          Sets the conflict resolver to use for this repository.
 void setEventStore(EventStore eventStore)
          Sets the event store that would physically store the events.
 void setEventStreamDecorators(List<? extends EventStreamDecorator> eventProcessors)
          Sets the Event Stream Decorators that will process the event in the DomainEventStream when read, or written to the event store.
 void setSnapshotterTrigger(SnapshotterTrigger snapshotterTrigger)
          Sets the snapshotter trigger for this repository.
protected  void validateOnLoad(T aggregate, Long expectedVersion)
          Checks the aggregate for concurrent changes.
 
Methods inherited from class org.axonframework.repository.LockingRepository
doSave, load
 
Methods inherited from class org.axonframework.repository.AbstractRepository
add, load, setEventBus
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface org.axonframework.eventsourcing.AggregateFactory
getTypeIdentifier
 

Constructor Detail

EventSourcingRepository

protected EventSourcingRepository()
Initializes a repository with the default locking strategy.

See Also:
LockingRepository.LockingRepository()

EventSourcingRepository

protected EventSourcingRepository(LockingStrategy lockingStrategy)
Initialize a repository with the given locking strategy.

Parameters:
lockingStrategy - the locking strategy to apply to this
Method Detail

doSaveWithLock

protected void doSaveWithLock(T aggregate)
Perform the actual saving of the aggregate. All necessary locks have been verified.

Specified by:
doSaveWithLock in class LockingRepository<T extends EventSourcedAggregateRoot>
Parameters:
aggregate - the aggregate to store

doLoad

protected T doLoad(AggregateIdentifier aggregateIdentifier,
                   Long expectedVersion)
Perform the actual loading of an aggregate. The necessary locks have been obtained.

Specified by:
doLoad in class LockingRepository<T extends EventSourcedAggregateRoot>
Parameters:
aggregateIdentifier - the identifier of the aggregate to load
expectedVersion - The expected version of the loaded aggregate
Returns:
the fully initialized aggregate
Throws:
AggregateDeletedException - in case an aggregate existed in the past, but has been deleted
AggregateNotFoundException - when an aggregate with the given identifier does not exist

createAggregate

public T createAggregate(AggregateIdentifier aggregateIdentifier,
                         DomainEvent firstEvent)
Instantiate the aggregate using the given aggregate identifier and first event. The first event of the event stream is passed to allow the factory to identify the actual implementation type of the aggregate to create. The first event can be either the event that created the aggregate or, when using event sourcing, a snapshot event. In either case, the event should be designed, such that these events contain enough information to deduct the actual aggregate type.

This implementation is aware of the AggregateSnapshot type events. When firstEvent is an instance of AggregateSnapshot, the aggregate is extracted from the event. Otherwise, aggregate creation is delegated to the abstract instantiateAggregate(org.axonframework.domain.AggregateIdentifier, org.axonframework.domain.DomainEvent) method.

Specified by:
createAggregate in interface AggregateFactory<T extends EventSourcedAggregateRoot>
Parameters:
aggregateIdentifier - the aggregate identifier of the aggregate to instantiate
firstEvent - The first event in the event stream. This is either the event generated during creation of the aggregate, or a snapshot event
Returns:
an aggregate ready for initialization using a DomainEventStream.

instantiateAggregate

protected abstract T instantiateAggregate(AggregateIdentifier aggregateIdentifier,
                                          DomainEvent firstEvent)
Instantiate the aggregate using the given aggregate identifier and first event. The first event of the event stream is passed to allow the repository to identify the actual implementation type of the aggregate to create. The first event can be either the event that created the aggregate or, when using event sourcing, a snapshot event. In either case, the event should be designed, such that these events contain enough information to deduct the actual aggregate type.

Note that aggregate state should *not* be initialized by this method. That means, no events should be applied by a call to this method. The first event is passed to allow the implementation to base the exact type of aggregate to instantiate on that event.

Parameters:
aggregateIdentifier - the aggregate identifier of the aggregate to instantiate
firstEvent - The first event in the event stream. This is either the event generated during creation of the aggregate, or a snapshot event
Returns:
an aggregate ready for initialization using a DomainEventStream.

validateOnLoad

protected void validateOnLoad(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

This implementation will do nothing if a conflict resolver (See setConflictResolver(ConflictResolver) is set. Otherwise, it will call super.validateOnLoad(...).

Overrides:
validateOnLoad in class AbstractRepository<T extends EventSourcedAggregateRoot>
Parameters:
aggregate - The loaded aggregate
expectedVersion - The expected version of the aggregate

setEventStore

public void setEventStore(EventStore eventStore)
Sets the event store that would physically store the events.

Parameters:
eventStore - the event bus to publish events to

setEventStreamDecorators

public void setEventStreamDecorators(List<? extends EventStreamDecorator> eventProcessors)
Sets the Event Stream Decorators that will process the event in the DomainEventStream when read, or written to the event store.

When appending events to the event store, the processors are invoked in the reverse order, causing the first decorator in this list to receive each event first. When reading from events, the decorators are invoked in the order given.

Parameters:
eventProcessors - The processors to that will process events in the DomainEventStream

setSnapshotterTrigger

public void setSnapshotterTrigger(SnapshotterTrigger snapshotterTrigger)
Sets the snapshotter trigger for this repository.

Parameters:
snapshotterTrigger - the snapshotter trigger for this repository.

setConflictResolver

public void setConflictResolver(ConflictResolver conflictResolver)
Sets the conflict resolver to use for this repository. If not set (or null), the repository will throw an exception if any unexpected changes appear in loaded aggregates.

Parameters:
conflictResolver - The conflict resolver to use for this repository


Copyright © 2011. All Rights Reserved.