Class InMemoryRepository<ID,E>

java.lang.Object
org.axonframework.modelling.repository.InMemoryRepository<ID,E>
Type Parameters:
ID - The type of identifier for entities in this repository.
E - The type of entity stored in this repository.
All Implemented Interfaces:
DescribableComponent, Repository<ID,E>, Repository.LifecycleManagement<ID,E>

public class InMemoryRepository<ID,E> extends Object implements Repository.LifecycleManagement<ID,E>
In-memory implementation of the Repository interface that stores entities in a ConcurrentHashMap. This implementation uses a SimpleRepository as a delegate to handle entity lifecycle management while providing persistent storage in memory.

This repository is suitable for testing purposes, prototyping, or scenarios where entities need to be stored in memory without external persistence. The storage is thread-safe through the use of ConcurrentHashMap.

The repository automatically manages entity lifecycle through the SimpleRepository delegate, ensuring proper integration with the ProcessingContext and automatic persistence on commit.

Example usage:


 InMemoryRepository<String, MyEntity> repository = new InMemoryRepository<>(
     String.class,
     MyEntity.class
 );
 
Since:
5.0.0
Author:
Mateusz Nowak
  • Constructor Details

    • InMemoryRepository

      public InMemoryRepository(@Nonnull Class<ID> idType, @Nonnull Class<E> entityType)
      Constructs a new InMemoryRepository for entities of type entityType with identifiers of type idType.

      The repository uses a ConcurrentHashMap as the underlying storage mechanism and delegates entity lifecycle management to a SimpleRepository.

      Parameters:
      idType - The type of the identifier for entities in this repository.
      entityType - The type of entity stored in this repository.
  • Method Details

    • attach

      public ManagedEntity<ID,E> attach(@Nonnull ManagedEntity<ID,E> entity, @Nonnull ProcessingContext processingContext)
      Description copied from interface: Repository.LifecycleManagement
      Ensures that the given entity has its lifecycle managed in the given processingContext. This ensures that when the processingContext commits, any changes detected in the entity state are persisted in this repository's underlying storage, if present.

      If a managed entity for this identifier was already present in the ProcessingContext, the new instance will replace it.

      Repositories may wrap entities. In that case, the returned instance may not be exactly the same (`==` comparison) as the instance provided. It is always recommended to use the returned instance.

      Specified by:
      attach in interface Repository.LifecycleManagement<ID,E>
      Parameters:
      entity - The entity to have its lifecycle attached to the given processing context.
      processingContext - The processing context to link the lifecycle with.
      Returns:
      The instance of the entity whose lifecycle is managed by this repository.
    • entityType

      @Nonnull public Class<E> entityType()
      Description copied from interface: Repository
      The type of entity stored in this repository.
      Specified by:
      entityType in interface Repository<ID,E>
      Returns:
      The type of entity stored in this repository.
    • idType

      @Nonnull public Class<ID> idType()
      Description copied from interface: Repository
      The type of the identifier used to identify entities in this repository.
      Specified by:
      idType in interface Repository<ID,E>
      Returns:
      The type of the identifier used to identify entities in this repository.
    • load

      public CompletableFuture<ManagedEntity<ID,E>> load(@Nonnull ID identifier, @Nonnull ProcessingContext processingContext)
      Description copied from interface: Repository
      Load the entity with the given unique identifier. No version checks are done when loading an entity, meaning that concurrent access will not be checked for.
      Specified by:
      load in interface Repository<ID,E>
      Parameters:
      identifier - The identifier of the entity to load.
      processingContext - The processing context in which to manage the lifecycle of the entity.
      Returns:
      A CompletableFuture resolving to the ManagedEntity with the given identifier, or null if it can't be found.
    • loadOrCreate

      public CompletableFuture<ManagedEntity<ID,E>> loadOrCreate(@Nonnull ID identifier, @Nonnull ProcessingContext processingContext)
      Description copied from interface: Repository
      Loads an entity from the repository.
      Specified by:
      loadOrCreate in interface Repository<ID,E>
      Parameters:
      identifier - The identifier of the entity to load.
      processingContext - The processing context in which to manage the lifecycle of the entity.
      Returns:
      A CompletableFuture resolving to the ManagedEntity with the given identifier, or a newly constructed entity instance based on the factoryMethod.
    • persist

      public ManagedEntity<ID,E> persist(@Nonnull ID identifier, @Nonnull E entity, @Nonnull ProcessingContext processingContext)
      Description copied from interface: Repository
      Persists the given entity in this repository
      Specified by:
      persist in interface Repository<ID,E>
      Parameters:
      identifier - The identifier of the entity.
      entity - The current state of the entity to store.
      processingContext - The ProcessingContext in which the entity is active.
      Returns:
      a ManagedEntity wrapping the entity managed in the ProcessingContext.
    • describeTo

      public void describeTo(@Nonnull ComponentDescriptor descriptor)
      Description copied from interface: DescribableComponent
      Describe the properties of this DescribableComponent with the given descriptor.

      Components should call the appropriate describeProperty methods on the descriptor to register their properties. The descriptor is responsible for determining how these properties are formatted and structured in the final output.

      Best Practices: As a general rule, all relevant fields of a DescribableComponent implementation should be described in this method. However, developers have discretion to include only the fields that make sense in the context. Not every field may be meaningful for description purposes, especially internal implementation details. Furthermore, components might want to expose different information based on their current state. The final decision on what properties to include lies with the person implementing the describeTo method, who should focus on providing information that is useful for understanding the component's configuration and state.

      Example implementation:

       public void describeTo(ComponentDescriptor descriptor) {
           descriptor.describeProperty("name", this.name);
           descriptor.describeProperty("enabled", this.enabled);
           descriptor.describeProperty("configuration", this.configuration); // A nested component
           descriptor.describeProperty("handlers", this.eventHandlers);      // A collection
       }
       
      Specified by:
      describeTo in interface DescribableComponent
      Parameters:
      descriptor - The component descriptor to describe this DescribableComponentn its properties in.