fluent-nhibernate
fluent-nhibernate copied to clipboard
Default enum type mapping prevents using imported type in HQL queries
Problem
Mapping an enum property without specifying a custom type prevents using the imported enum type in HQL queries.
e.g.
public class Foo { public Bar Status { get; set; } }
public enum Bar { X, Y }
public class FooMapping : ClassMap<Foo>
{
public FooMapping()
{
Map(x => x.Status);
ImportType<Bar>();
}
}
session.CreateQuery("FROM Foo WHERE Status = Bar.Y").List<Foo>();
See, https://github.com/chilversc/FNH-EnumError for a sample project that reproduces this error.
Expected behaviour
The query should work and return a list of foo's that have their status equal to Y.
Actual behaviour
The query fails with an exception from the database driver with the message, "Column Y not found".
Workaround
In the mapping specify Map(x => x.Status).CustomType("")
Tested out some other types:
// This works
Map (x => x.Bar).CustomType ("");
Map (x => x.Bar).CustomType (typeof(NHibernate.Type.EnumType<Bar>));
// This does not work
Map (x => x.Bar);
Map (x => x.Bar).CustomType (typeof(FluentNHibernate.Mapping.GenericEnumMapper<Bar>));
Map (x => x.Bar).CustomType (typeof(NHibernate.Type.EnumStringType<Bar>));
Looking at the various types, the key seems to be NHibernate.Type.PersistentEnumType, which seems to be the default class NHibernate uses if you don't specify.
this should work too
Map (x => x.Status).CustomType<Bar>();
I researched this problem a bit.
This can be fixed by simple change (check referenced commit) No Unit tests are red. Everything is green. I am still researching the problem and differences between EnumStringType and EnumType
Thanks
This is a breaking change. This change will make all the default strings enums being saved as integer types (which is the normal behaviour of Nhibernate). But Fluent could be used with this assumption that by default my Enum is saved in form of string. So we can't easilly do this change. Especially when there is a simple workaround. Dunno how many people #151 affects, first we would have to think if this is really worthwhile to make this change.
I also researched how the schema looks like and the reason why this works
Map (x => x.Bar).CustomType ("");
Is that, with this statement enum is stored as int.