Class HierarchicalStateManager
- All Implemented Interfaces:
DescribableComponent,StateManager
StateManager that can load an entity from two delegates, giving preference to the child delegate and then the
parent. This is useful to encapsulate a set of repositories that are only relevant in a specific context, such as a
specific Module.
Any registrations of Repository will be done on the child StateManager.
- Since:
- 5.0.0
- Author:
- Mitchell Herrijgers
-
Method Summary
Modifier and TypeMethodDescriptionstatic HierarchicalStateManagercreate(StateManager parent, StateManager child) Creates a new hierarchicalStateManagerthat delegates to the givenparentandchildmanagers, giving preference to thechildmanager.voiddescribeTo(ComponentDescriptor descriptor) Describe the properties ofthis DescribableComponentwith the givendescriptor.getChild()Returns the childStateManagerof thisHierarchicalStateManager.Returns the parentStateManagerof thisHierarchicalStateManager.<I,T> CompletableFuture <ManagedEntity<I, T>> loadManagedEntity(Class<T> type, I id, ProcessingContext context) <I,T> StateManager register(Repository<I, T> repository) Registers anRepositoryfor use with thisStateManager.The types of entities that are registered with thisStateManager.registeredIdsFor(Class<?> entityType) The types of identifiers that are registered with thisStateManagerfor the givenentityType.<I,T> @Nullable Repository <I, T> repository(Class<T> entityType, Class<I> idType) Returns theRepositoryfor the giventype.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.axonframework.modelling.StateManager
loadEntity, register
-
Method Details
-
create
Creates a new hierarchicalStateManagerthat delegates to the givenparentandchildmanagers, giving preference to thechildmanager.- Parameters:
parent- The parentStateManagerto delegate if the childStateManagercannot load the entity.child- The childStateManagerto try first.- Returns:
- A new hierarchical
StateManagerthat delegates to the given managers.
-
register
Description copied from interface:StateManagerRegisters anRepositoryfor use with thisStateManager. The combination ofRepository.entityType()andRepository.idType()must be unique for all registered repositories.- Specified by:
registerin interfaceStateManager- Type Parameters:
I- the type of idT- the type of the entity- Parameters:
repository- theRepositoryto use for loading state- Returns:
- this
StateManagerfor fluent interfacing
-
loadManagedEntity
public <I,T> CompletableFuture<ManagedEntity<I,T>> loadManagedEntity(Class<T> type, I id, ProcessingContext context) Retrieves aManagedEntityof the giventypeandid. TheCompletableFuturewill resolve to aManagedEntity, or complete exceptionally if it could not be resolved.Delegates directly to
StateManager#loadManagedEntity(Class, Object, ProcessingContext)of thechild, falling back to theparentwhen the child completes exceptionally with aMissingRepositoryException. Delegating the load itself, rather than first locating aRepositorythroughrepository(Class, Class)and invoking it here, ensures each delegate applies its own resolution semantics fortype.SimpleStateManager, for instance, resolves aRepositoryregistered for a supertype when asked for a subtype, whereasrepository(Class, Class)only matches the exact registered type. Re-implementing that resolution here would either duplicate or diverge from the delegate's own behavior; callingloadManagedEntityavoids that entirely, and still composes correctly when the delegate is itself aHierarchicalStateManager.Delegates such as
SimpleStateManagercomplete theirCompletableFutureexceptionally rather than throwingMissingRepositoryExceptionsynchronously, so the parent fallback is expressed withCompletableFuture.exceptionallyCompose(java.util.function.Function)rather than atry/catch. The child call is nonetheless wrapped inFutureUtils.runFailing(java.util.function.Supplier)so a delegate that still throwsMissingRepositoryExceptionsynchronously also triggers the fallback. Any other exception is propagated to the caller unchanged. OnlyMissingRepositoryExceptiontriggers the fallback; aLoadedEntityNotOfExpectedTypeException, for instance, does not, since by the time it surfaces the child'sloadOrCreatemay already have attached state to theProcessingContext, making a retry against the parent unsound.- Specified by:
loadManagedEntityin interfaceStateManager- Type Parameters:
I- the type of the identifier of the entityT- the type of the entity- Parameters:
type- the type of state to retrieveid- the id of the state to retrievecontext- thecontextto load the entity in- Returns:
- a
CompletableFuturewhich resolves to the entity instance, or completes exceptionally with aMissingRepositoryExceptionwhen thisStateManagerdoes not control theRepositoryto load theManagedEntityfrom
-
registeredEntities
Description copied from interface:StateManagerThe types of entities that are registered with thisStateManager.- Specified by:
registeredEntitiesin interfaceStateManager- Returns:
- the types of entities that are registered with this
StateManager
-
registeredIdsFor
Description copied from interface:StateManagerThe types of identifiers that are registered with thisStateManagerfor the givenentityType.- Specified by:
registeredIdsForin interfaceStateManager- Parameters:
entityType- the type of the entity- Returns:
- the types of identifiers that are registered with this
StateManagerfor the givenentityType
-
repository
Description copied from interface:StateManagerReturns theRepositoryfor the giventype.Returns
nullif no repository is registered for the given type and id.Unlike
StateManager.loadManagedEntity(Class, Object, ProcessingContext), which resolves aRepositoryregistered for a supertype when asked for a subtype, this method only matches an exactly registered(entityType, idType)pair. Hence, there is no supertype or subtype resolution.- Specified by:
repositoryin interfaceStateManager- Type Parameters:
I- the type of the identifier of the entityT- the type of the entity- Parameters:
entityType- the type of the entityidType- the type of the identifier of the entity- Returns:
- the
Repositoryfor the givenidTypeandentityType
-
getParent
Returns the parentStateManagerof thisHierarchicalStateManager.- Returns:
- The parent
StateManagerof thisHierarchicalStateManager.
-
getChild
Returns the childStateManagerof thisHierarchicalStateManager.- Returns:
- The child
StateManagerof thisHierarchicalStateManager.
-
describeTo
Description copied from interface:DescribableComponentDescribe the properties ofthis DescribableComponentwith the givendescriptor.Components should call the appropriate
describePropertymethods 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
DescribableComponentimplementation 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 thedescribeTomethod, 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:
describeToin interfaceDescribableComponent- Parameters:
descriptor- The component descriptor to describethis DescribableComponentn its properties in.
-