Getting Started

Simple NHibernate Persistence Usage

NuGet Package: NServiceBus.NHibernate (10-pre)
Target Version: NServiceBus 9.x
This page targets a pre-release version. Pre-releases are subject to change and samples are not guaranteed to be fully functional.


The sample relies on the availability of a SQL Server named .\SqlExpress and the existence of a database named Samples.NHibernate.

Code walk-through

This sample shows a simple client/server scenario.

  • Client sends a StartOrder message to Server.
  • Server starts an OrderSaga.
  • OrderSaga requests a timeout with CompleteOrder data.
  • When the CompleteOrder timeout fires, the OrderSaga publishes an OrderCompleted event.
  • Server then publishes a message that the client has subscribed to.
  • Client handles the OrderCompleted event.

NHibernate config

NHibernate is configured with the right driver, dialect, and connection string. Then, since NHibernate needs a way to map the class to the database table, the configuration code does this using the ModelMapper API. Finally, the configuration is used to run the endpoint.

var endpointConfiguration = new EndpointConfiguration("Samples.NHibernate.Server");
var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();

// for SqlExpress use Data Source=.\SqlExpress;Initial Catalog=Samples.NHibernate;Integrated Security=True;Max Pool Size=100;Encrypt=false
var connectionString = @"Server=localhost,1433;Initial Catalog=Samples.NHibernate;User Id=SA;Password=yourStrong(!)Password;Max Pool Size=100;Encrypt=false";
var hibernateConfig = new Configuration();
hibernateConfig.DataBaseIntegration(x =>
    x.ConnectionString = connectionString;



Order saga data

Note that to use NHibernate's lazy-loading feature, all properties on the saga data class must be virtual.

public class OrderSagaData :
    public virtual Guid OrderId { get; set; }
    public virtual string OrderDescription { get; set; }

Order saga

public class OrderSaga :
    static ILog log = LogManager.GetLogger<OrderSaga>();

    protected override void ConfigureHowToFindSaga(SagaPropertyMapper<OrderSagaData> mapper)
        mapper.ConfigureMapping<StartOrder>(message => message.OrderId)
            .ToSaga(sagaData => sagaData.OrderId);

    public Task Handle(StartOrder message, IMessageHandlerContext context)
        Data.OrderId = message.OrderId;
        var orderDescription = $"The saga for order {message.OrderId}";
        Data.OrderDescription = orderDescription;
        log.Info($"Received StartOrder message {Data.OrderId}. Starting Saga");

        var shipOrder = new ShipOrder
            OrderId = message.OrderId

        log.Info("Order will complete in 5 seconds");
        var timeoutData = new CompleteOrder
            OrderDescription = orderDescription

        return Task.WhenAll(
            RequestTimeout(context, TimeSpan.FromSeconds(5), timeoutData)

    public Task Timeout(CompleteOrder state, IMessageHandlerContext context)
        log.Info($"Saga with OrderId {Data.OrderId} completed");
        var orderCompleted = new OrderCompleted
            OrderId = Data.OrderId
        return context.Publish(orderCompleted);

Handler using ISession

The handler uses the ISession instance to store business data.

public class ShipOrderHandler :
    public Task Handle(ShipOrder message, IMessageHandlerContext context)
        var session = context.SynchronizedStorageSession.Session();
        var orderShipped = new OrderShipped
            Id = message.OrderId,
            ShippingDate = DateTime.UtcNow,


        return Task.CompletedTask;

The database

Data in the database is stored in three different tables.

The saga data

  • IContainSagaData.Id maps to the OrderSagaData primary key and unique identifier column Id.
  • IContainSagaData.Originator and IContainSagaData.OriginalMessageId map to columns of the same name with type varchar(255).
  • Custom properties on SagaData, in this case OrderDescription and OrderId, are also mapped to columns with the same name and the respecting types.

The handler stored data

Related Articles

  • Persistence
    Features of NServiceBus requiring persistence include timeouts, sagas, and subscription storage.
  • Sagas
    NServiceBus uses event-driven architecture to include fault-tolerance and scalability in long-term business processes.

Last modified