Skip to content

AggregateRepository

Defined in: packages/ddd-mikro-orm/src/repository/aggregate.repository.ts:58

Base class for the command repositories that load and save an existing aggregate.

Provides authoritative aggregate hydration via findById:

  • Bypasses read-side caches (@FromCache) to prevent stale reads on mutation paths.
  • Forces MikroORM { refresh: true } to avoid returning stale Unit-of-Work identity-map entities.
  • Translates low-level driver failures through mapPersistenceError into application-neutral transient signals.

Concrete repositories extend this class, inject dependencies into super(...), and provide their decorated save() method, usually through @PersistedWrite. The store is any IEntityManagerSource, typically the application’s own store; its em is also what save() passes to optimisticUpdate or optimisticDelete.

// A NestJS provider; STORE is the application's IEntityManagerSource token.
@Injectable()
export class UpdateUserCommandRepository extends AggregateRepository<
UserSnapshot,
User,
UserSnapshot
> {
constructor(
@Inject(CACHE_TOKEN) cache: ICache<UserSnapshot>,
@Inject(STORE) store: IEntityManagerSource,
) {
super(cache, store, User, User.aggregateName, User.fromJSON);
}
@PersistedWrite<User>({
unique: { email: (user) => new UniqueEmailException(user) },
})
async save(user: User): Promise<UserSnapshot> {
...
}
}

TSnapshot extends Partial<RootEntitySnapshot>

Snapshot structure of the aggregate.

TEntity extends RootEntity<TSnapshot>

Domain aggregate class extending RootEntity.

TResult = unknown

Persisted result type returned by save().

new AggregateRepository<TSnapshot, TEntity, TResult>(cache, store, entityClass, aggregateName, hydrateFn): AggregateRepository<TSnapshot, TEntity, TResult>

Defined in: packages/ddd-mikro-orm/src/repository/aggregate.repository.ts:66

ICache<TSnapshot>

IEntityManagerSource

EntityName<TEntity>

string

(snapshot) => TEntity

AggregateRepository<TSnapshot, TEntity, TResult>

CommandRepository.constructor

protected readonly aggregateName: string

Defined in: packages/ddd-mikro-orm/src/repository/aggregate.repository.ts:70


protected readonly cache: ICache<TSnapshot>

Defined in: packages/ddd-core/dist/persistence/command-repository.abstract.d.ts:35

CommandRepository.cache


protected readonly entityClass: EntityName<TEntity>

Defined in: packages/ddd-mikro-orm/src/repository/aggregate.repository.ts:69


protected readonly hydrateFn: (snapshot) => TEntity

Defined in: packages/ddd-mikro-orm/src/repository/aggregate.repository.ts:71

TSnapshot

TEntity


protected readonly store: IEntityManagerSource

Defined in: packages/ddd-mikro-orm/src/repository/aggregate.repository.ts:68

findById(id): Promise<TEntity | null>

Defined in: packages/ddd-mikro-orm/src/repository/aggregate.repository.ts:99

Loads the authoritative aggregate directly from persistence.

Enforces { refresh: true } so that if the entity was already loaded in the active EntityManager’s identity map, its columns are re-fetched from the database before domain mutations and optimistic concurrency checks take place. The manager comes from store.em, read for this call.

string

The aggregate identifier.

Promise<TEntity | null>

Rehydrated aggregate instance, or null if not found.

If a retryable database connection or driver error occurs.

IWriteSideAggregateRepository.findById


abstract save(entity): Promise<TResult | null>

Defined in: packages/ddd-core/dist/persistence/command-repository.abstract.d.ts:37

Persists the aggregate/payload.

Returning null is the conventional deletion result used by the DDD cache decorator to trigger eviction/barrier behavior.

TEntity

Promise<TResult | null>

IWriteSideAggregateRepository.save

CommandRepository.save