1
votes

We have an NServiceBus service configured to run sagas. With InMemory-persistence everything runs fine. When trying to change the profile to NServiceBus.Integration, we get an error when starting the service.

Endpoint configuration:

public class MyEndpoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    private IContainer _container;

    public void Init()
    {
        log4net.Config.XmlConfigurator.Configure();
        SetupStructureMap();

        Configure.With()
            .Log4Net()
            .StructureMapBuilder(_container)
            .Sagas()
            .XmlSerializer();
    }

    private void SetupStructureMap()
    {
        [...]
    }
}

Error message:

    FATAL 2012-01-18 11:11:52,197  2640ms GenericHost            Start              - FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

      * Database was not configured through Database method.
     ---> System.ArgumentException: The number of generic arguments provided doesn't equal the arity of the generic type definition.
    Parameter name: instantiation
       at System.RuntimeType.MakeGenericType(Type[] instantiation)
       at FluentNHibernate.Automapping.AutoMapManyToMany.GetInverseProperty(PropertyInfo property)
       at FluentNHibernate.Automapping.AutoMapManyToMany.MapsProperty(PropertyInfo property)
       at FluentNHibernate.Automapping.AutoMapper.TryToMapProperty(ClassMappingBase mapping, PropertyInfo property, IList`1 mappedProperties)
       at FluentNHibernate.Automapping.AutoMapper.MapEverythingInClass(ClassMappingBase mapping, Type entityType, IList`1 mappedProperties)
       at FluentNHibernate.Automapping.AutoMapper.MergeMap(Type classType, ClassMappingBase mapping, IList`1 mappedProperties)
       at FluentNHibernate.Automapping.AutoMapper.Map(Type classType, List`1 types)
       at FluentNHibernate.Automapping.AutoPersistenceModel.AddMapping(Type type)
       at FluentNHibernate.Automapping.AutoPersistenceModel.CompileMappings()
       at FluentNHibernate.Cfg.AutoMappingsContainer.Apply(Configuration cfg)
       at FluentNHibernate.Cfg.MappingConfiguration.Apply(Configuration cfg)
       at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()
       --- End of inner exception stack trace ---
       at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()
       at NServiceBus.SagaPersisters.NHibernate.Config.Internal.SessionFactoryBuilder.UpdateDatabaseSchemaUsing(FluentConfiguration fluentConfiguration)
       at NServiceBus.SagaPersisters.NHibernate.Config.Internal.SessionFactoryBuilder.Build(IDictionary`2 nhibernateProperties, Boolean updateSchema)
       at NServiceBus.ConfigureNHibernateSagaPersister.NHibernateSagaPersister(Configure config, IDictionary`2 nhibernateProperties, Boolean autoUpdateSchema)
       at NServiceBus.ConfigureNHibernateSagaPersister.NHibernateSagaPersisterWithSQLiteAndAutomaticSchemaGeneration(Configure config)
       at NServiceBus.Host.Internal.ProfileHandlers.IntegrationProfileHandler.NServiceBus.IHandleProfile.ProfileActivated()
       at NServiceBus.Host.Internal.ProfileManager.<ActivateProfileHandlers>b__14(IHandleProfile hp)
       at System.Collections.Generic.List`1.ForEach(Action`1 action)
       at NServiceBus.Host.Internal.ProfileManager.ActivateProfileHandlers()
       at NServiceBus.Host.Internal.GenericHost.Start()

      * Database was not configured through Database method.

Configuration file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
        <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
        <section name="MsmqSubscriptionStorageConfig" type="NServiceBus.Config.MsmqSubscriptionStorageConfig,NServiceBus.Core" />
    </configSections>
    <MsmqTransportConfig InputQueue="MyQueue" ErrorQueue="MyQueueError" NumberOfWorkerThreads="1" MaxRetries="5" />

    <UnicastBusConfig>
        <MessageEndpointMappings>
            <add Messages="My.MessageContracts" Endpoint="MyQueue" />
        </MessageEndpointMappings>
    </UnicastBusConfig>
    <log4net debug="false">
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
            <file value="C:\Log\My.log" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="10" />
            <maximumFileSize value="10MB" />
            <staticLogFileName value="true" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
            </layout>
        </appender>
        <root>
            <level value="INFO" />
            <appender-ref ref="RollingLogFileAppender" />
        </root>
    </log4net>
</configuration>
2
We are by the way running NServiceBus 2.6.Alf Kåre Lefdal
Can you include your config file so that we can see that you included everything?Udi Dahan
Configuration file now added.Alf Kåre Lefdal
Seems like the automapping fails, can you add your saga entity class?Andreas Öhlund
Seems like we have done everything wrong when designing the SagaData class. Members were not virtual, many members were of types that could not be handled by NServicebus. We will look more in to this tomorrow, and then come back with an update here.Alf Kåre Lefdal

2 Answers

2
votes

Looks like you are missing the following from the config, it is in the app.config of the OrderService in the samples:

<section name="DBSubscriptionStorageConfig" type="NServiceBus.Config.DBSubscriptionStorageConfig, NServiceBus.Core" />
<section name="NHibernateSagaPersisterConfig" type="NServiceBus.Config.NHibernateSagaPersisterConfig, NServiceBus.Core" />

<DBSubscriptionStorageConfig>
    <NHibernateProperties>
      <add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider"/>
      <add Key="connection.driver_class" Value="NHibernate.Driver.SQLite20Driver"/>
      <add Key="connection.connection_string" Value="Data Source=.\Subscriptions.sqlite;Version=3;New=True;"/>
      <add Key="dialect" Value="NHibernate.Dialect.SQLiteDialect"/>
    </NHibernateProperties>
  </DBSubscriptionStorageConfig>

<NHibernateSagaPersisterConfig>
    <NHibernateProperties>
      <add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider"/>
      <add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver"/>
      <add Key="connection.connection_string" Value="Server=localhost;initial catalog=NServiceBus;Integrated Security=SSPI"/>
      <add Key="dialect" Value="NHibernate.Dialect.MsSql2000Dialect"/>
    </NHibernateProperties>
  </NHibernateSagaPersisterConfig>
0
votes

The problem was, as Andreas touched upon, on persisting the SagaData-class using NHibernate/Fluent NHibernate.

Just to summarize all the things that were wrong:

  • In order to use the profile NServicebus.Integration, you need to add a reference to SQLite (use NuGet)
  • In order to use the profile NServiceBus.Production, you need to set up connection to the database in app.config, as Adam showed in his answer.
  • In order to use both these two profiles, your SagaData-class must be playing by the rules of NHibernate:
    • All properties must be virtual
    • The class must not be sealed
    • The same goes for the type of all properties

All this is for NServiceBus 2.6. In 3.0, which is in Beta6 now, they use RavenDB instead, with no binding to NHibernate or SQLite. How the transition from 2.6 to 3.0 is, I do not know yet, but I think this is the way we are going on this project.