Skip to content

ADR-0006: NHibernate as the primary ORM

  • Status: Accepted
  • Date: 2026-01-01
  • Deciders: Data Architect, Backend Lead
  • Tags: persistence, data, orm

Context

Transactional metadata (aggregates, registries, lifecycle state) is stored in Azure SQL / PostgreSQL with a database-per-service model (see Data Architecture). The platform needs a mature ORM that supports rich domain mapping for DDD aggregates, row-level tenant filtering, and second-level caching, and is already grounded in the ConnectSoft.Extensions.* data libraries and templates.

Decision

Use NHibernate as the primary ORM for transactional stores. Tenant isolation is enforced through tenantId participation in indexes and row-level filtering in NHibernate; each store has a single owning service.

Consequences

Positive

  • Rich mapping for DDD aggregates and value objects; mature filtering and caching.
  • Consistent data-access pattern baked into templates.

Negative / trade-offs

  • Mapping/configuration learning curve; care needed for query performance.

Neutral

  • Document-shaped data uses Cosmos DB rather than the relational ORM.

Alternatives considered

Alternative Why not chosen
Entity Framework Core Viable, but platform libraries/templates are standardized on NHibernate.
Dapper / micro-ORM Insufficient domain-mapping and filtering for aggregate-heavy domains.