You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm having a bit of trouble with some SQL generated by my FluentNHibernate mappings. I'm not doing anything too complex, but unfortunately it's not behaving the way I would have expected.
I have a table-per-type hierarchy relating a ContentModule table to several sub-type tables. For the CategoryContentModule and EventContentModule types, there is an additional one-to-many relationship to the ContentItem table.
Here's the class definition for my tables; make note of the intermediary abstract type ContentItemContentModule:
public abstract class ContentModule
{
public virtual string Name { get; set; }
public virtual ModuleStatus Status { get; set; }
public virtual DateTime? ExpirationDateTime { get; set; }
public virtual DateTime? LastPublishedDateTime { get; set; }
public virtual DateTime? LastUnpublishedDateTime { get; set; }
}
public class CustomContentModule : ContentModule
{
public virtual string ViewPath { get; set; }
}
public abstract class ContentItemContentModule : ContentModule
{
public virtual ContentItem ContentItem { get; set; }
}
public class EventContentModule : ContentItemContentModule
{
public virtual Event Event { get; set; }
}
public class CategoryContentModule : ContentItemContentModule
{
public virtual Category Category { get; set; }
}
Finally, my mappings:
public class ContentModuleMapping : ClassMap<ContentModule>
{
public ContentModuleMapping()
{
Map(x => x.Name);
Map(x => x.Status).CustomType<ContentModule.ModuleStatus>();
Map(x => x.ExpirationDateTime);
Map(x => x.LastPublishedDateTime);
Map(x => x.LastUnpublishedDateTime);
}
}
public class CustomContentModuleMapping : SubclassMap<CustomContentModule>
{
public CustomContentModuleMapping()
{
Map(x => x.ViewPath).Not.Nullable();
}
}
public class EventContentModuleMapping : SubclassMap<EventContentModule>
{
public EventContentModuleMapping()
{
References(x => x.ContentItem).Nullable().Cascade.None();
References(x => x.Event).Not.Nullable().LazyLoad().Cascade.None();
}
}
public class CategoryContentModuleMapping : SubclassMap<CategoryContentModule>
{
public CategoryContentModuleMapping()
{
References(x => x.ContentItem).Nullable().Cascade.None();
References(x => x.Category).Not.Nullable().LazyLoad().Cascade.None();
}
}
As you can see, the intermediary type ContentItemContentModule is never mapped and exists only to provide the ContentItem property of its sub-types. In the mappings for each sub-type I explicitly map the ContentItem property.
When this mapping is registered and I attempt to retrieve a collection of ContentModule items via NHibernate, the generated SQL produces a non-existent column called ContentItemContentModuleId.
I've attempted explicitly setting the column name of the ContentItem reference to 'ContentItemId' (matching the table structure), but this did not work. After some experimentation I determined that referencing the ContentItem property was not the problem, but rather having the intermediary class ContentItemContentModule was. If I remove the intermediary abstract class and move the ContentItem property into each sub-type, the SQL is generated correctly and everything works.
The solution I came up with was simply to eliminate the intermediary abstract type and instead use an interface to achieve the same result in my code, but this is obviously a workaround.
TL;DR For some reason, FluentNHibernate is having problems with there being an unmapped abstract type between a mapped base abstract type and a mapped concrete type in a table-per-type hierarchy.
The text was updated successfully, but these errors were encountered:
I'm not an expert in mapping inheritance hierarchies, but if you use table-per-type, shouldn't all types in hierarchy be mapped, including abstract ones? Although I'm not sure what's Fluent default behaviour in this particular case
@chester89 While I do not disagree, the intermediary type is not intended to have its own table and if I map it, FluentNHibernate will assume that it does.
I'm having a bit of trouble with some SQL generated by my FluentNHibernate mappings. I'm not doing anything too complex, but unfortunately it's not behaving the way I would have expected.
I have a table-per-type hierarchy relating a ContentModule table to several sub-type tables. For the CategoryContentModule and EventContentModule types, there is an additional one-to-many relationship to the ContentItem table.
Here's the class definition for my tables; make note of the intermediary abstract type ContentItemContentModule:
Finally, my mappings:
As you can see, the intermediary type ContentItemContentModule is never mapped and exists only to provide the ContentItem property of its sub-types. In the mappings for each sub-type I explicitly map the ContentItem property.
When this mapping is registered and I attempt to retrieve a collection of ContentModule items via NHibernate, the generated SQL produces a non-existent column called ContentItemContentModuleId.
I've attempted explicitly setting the column name of the ContentItem reference to 'ContentItemId' (matching the table structure), but this did not work. After some experimentation I determined that referencing the ContentItem property was not the problem, but rather having the intermediary class ContentItemContentModule was. If I remove the intermediary abstract class and move the ContentItem property into each sub-type, the SQL is generated correctly and everything works.
The solution I came up with was simply to eliminate the intermediary abstract type and instead use an interface to achieve the same result in my code, but this is obviously a workaround.
TL;DR For some reason, FluentNHibernate is having problems with there being an unmapped abstract type between a mapped base abstract type and a mapped concrete type in a table-per-type hierarchy.
The text was updated successfully, but these errors were encountered: