Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
DavidBoike opened this issue Mar 10, 2023 · 0 comments
Open

Comments

@DavidBoike
Copy link
Member

DavidBoike commented Mar 10, 2023

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

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

No branches or pull requests

2 participants