Skip to content

Saga mapping generator touches class mappings not related to sagas #959

Open
@DavidBoike

Description

Describe the bug

Description

The saga persister makes an assumption that it needs to create indexes for all foreign-key relationships in the NHibernate context, because saga data could have sub-tables where the class type does not implement IContainSagaData.

This is probably a bad assumption now that synchronized storage exists, as a user would need to add their own non-saga classes to the NHibernate context in order to use them from a separate handler outside the saga.

Expected behavior

Saga mapper should leave mappings for non-saga-related classes alone.

Actual behavior

Saga mapper creates indexes for class mappings unrelated to the saga. Best case, this creates unnecessary indexes that the user didn't want. Worst case, under certain conditions (like two classes mapping to the same table) the endpoint can fail to start up because touching the same table twice would result in a duplicate index.

The endpoint can fail to start even if installers are disabled as the NHibernate configuration still has to be compiled in order to use the mappings in an endpoint.

Versions

All supported versions are likely affected.

Steps to reproduce

  1. Create and run a project using the code from this gist.
  2. Error is thrown on endpoint startup.

Relevant log output

Unhandled exception. NHibernate.MappingException: Index IDX_9669ABAB already exists!
   at NHibernate.Mapping.Table.AddIndex(Index index)
   at NServiceBus.SagaPersisters.NHibernate.AutoPersistence.SagaModelMapper.AddMappings(Configuration configuration, SagaMetadataCollection allSagaMetadata, IEnumerable`1 types, Func`2 tableNamingConvention) in /_/src/NServiceBus.NHibernate/SagaPersisters/SagaModelMapper.cs:line 68
   at NServiceBus.Features.NHibernateSagaStorage.ApplyMappings(ReadOnlySettings settings, Configuration configuration) in /_/src/NServiceBus.NHibernate/SagaPersisters/NHibernateSagaStorage.cs:line 48
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at NServiceBus.Features.NHibernateStorageSession.Setup(FeatureConfigurationContext context) in /_/src/NServiceBus.NHibernate/SynchronizedStorage/NHibernateStorageSession.cs:line 110
   at NServiceBus.Features.FeatureActivator.FeatureInfo.InitializeFrom(FeatureConfigurationContext featureConfigurationContext) in /_/src/NServiceBus.Core/Features/FeatureActivator.cs:line 225
   at NServiceBus.Features.FeatureActivator.ActivateFeature(FeatureInfo featureInfo, List`1 featuresToActivate, FeatureConfigurationContext featureConfigurationContext) in /_/src/NServiceBus.Core/Features/FeatureActivator.cs:line 188
   at NServiceBus.Features.FeatureActivator.SetupFeatures(FeatureConfigurationContext featureConfigurationContext) in /_/src/NServiceBus.Core/Features/FeatureActivator.cs:line 54
   at NServiceBus.EndpointCreator.Initialize() in /_/src/NServiceBus.Core/EndpointCreator.cs:line 59
   at NServiceBus.EndpointCreator.Create(SettingsHolder settings, Configuration hostingConfiguration) in /_/src/NServiceBus.Core/EndpointCreator.cs:line 25
   at NServiceBus.HostCreator.CreateWithInternallyManagedContainer(EndpointConfiguration endpointConfiguration) in /_/src/NServiceBus.Core/Hosting/HostCreator.cs:line 79
   at NServiceBus.Endpoint.Start(EndpointConfiguration configuration) in /_/src/NServiceBus.Core/Endpoint.cs:line 29
   at NHibernateRepro.Program.Main(String[] args) in C:\code\NHibernateRepro\Program.cs:line 37
   at NHibernateRepro.Program.<Main>(String[] args)

Additional Information

Workarounds

  • Don't use synchronized storage, and rely on distributed transactions.
  • Segregate sagas into their own endpoints without other NHibernate models.

Possible solutions

Instead of affecting all types, use reflection to create a map of only types

Additional information

None

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions