QueryOver making incorrect assumption about enums

333 views
Skip to first unread message

Greg

unread,
Mar 3, 2012, 10:52:25 PM3/3/12
to nhusers
NHibernate.Impl.ExpressionProcessor.ConvertType following line of
code:

if (type.IsEnum)
return Enum.ToObject(type, value);

I believe that is making an incorrect assumption about Enum being
ALWAYS mapped to a string in the DB. One could also map enums directly
to int. I do have some enums mapped to int, things work corrrectly by
using Criteria directly or by using LINQ. But not with QueryOver
because the code hits the above line.

I believe this is a bug which would be great to be fixed with the next
release. I am thinking that maybe code should check the metadata and
see if enum is mapped to an EnumStringType and only then return the
string represenation of the enum. Otherwise return its real value.

Or any other idea how to fix this issue?

On a side note, how does one get to be able to submit fixes/
enhancements to the NH code base? I am thinking of contributing as
much as time permits.

Greg

unread,
Mar 4, 2012, 9:31:55 AM3/4/12
to nhusers
I created a bug report for it: https://nhibernate.jira.com/browse/NH-3077
After paying some more thougtht, it seems to me like there isn't an
easy fix for this. Because at the point where this code is used, one
might have no session, not even a session factory, and so I guess no
access to the metadata, etc. I am pretty new to NHibernate though, so
any idea about workarounds, fixes is very much welcomed. One other not
so nice solution might be to use specific attributes to mark your enum
as not stored as strings in db. Or maybe better make this
ExpressionProcessor pluggable as to allow one to override convertion
logic and such.

Oskar Berggren

unread,
Mar 4, 2012, 12:47:53 PM3/4/12
to nhu...@googlegroups.com
2012/3/4 Greg <bor...@gmail.com>:

>
> On a side note, how does one get to be able to submit fixes/
> enhancements to the NH code base? I am thinking of contributing as
> much as time permits.

Contributions are most welcome!

Fork the project on github, read the contributor guide in the
top-level directory, commit each feature or fix on a separate branch,
generally follow good version control practices, and submit pull
requests using github. If you need to discuss development of
nhibernate itself, it can be done on the nhibernate-development
mailing list. If you are new to git I would recommend reading a decent
git best practices tutorial.

Oh, and there should be an issue reported in Jira for every fix or
feature of course.

/Oskar

Greg

unread,
Mar 4, 2012, 9:55:48 PM3/4/12
to nhusers
Thank you Oskar.

I created a bug report for this and uploaded unit tests. I looked more
into it and it seems like this is an issue that shows up only when I
cast the enum to string in my select list.
I found a workaround, if I declare an alias in the QueryOver<>(() =>
alias) then the problem goes away. I am thinking this is an issue
still, if I am not using casting to string then both tests succeed.
Casting to string throws things off for the first test.
I think I'll just make sure I always declare an alias with the
QueryOver declaration to avoid unexpected issues and time lost
uselessly.

[Test]
public void FilterAndTransformFail()
{
using (ISession session = this.OpenSession())
{
DTO dto = null;
var query = session.QueryOver<DomainClass>()
.SelectList(l => l
.Select(
Projections.Cast(NHibernateUtil.String,
Projections.Property<DomainClass>(a => a.Id))).WithAlias(() => dto.Id)
.Select(a => a.Name).WithAlias(() =>
dto.Name))
.OrderBy(a => a.Id).Asc;
query.Where(a => a.Id !=
ActionEnum.CampaignAddVisibility);

query.TransformUsing(Transformers.AliasToBean<DTO>()).Future<DTO>();
foreach (var q in query.List<DTO>())
{
Console.WriteLine(q.Name);
}
}
}

[Test]
public void FilterAndTransformSuccess()
{
using (ISession session = this.OpenSession())
{
DTO dto = null;
DomainClass dc = null;

var query = session.QueryOver<DomainClass>(() => dc)
.SelectList(l => l
.Select(
Projections.Cast(NHibernateUtil.String,
Projections.Property(() => dc.Id))).WithAlias(() => dto.Id)
.Select(() => dc.Name).WithAlias(() =>
dto.Name))
.OrderBy(() => dc.Id).Asc;
query.Where(() => dc.Id !=
ActionEnum.CampaignAddVisibility);

query.TransformUsing(Transformers.AliasToBean<DTO>()).Future<DTO>();
foreach (var q in query.List<DTO>())
{
Console.WriteLine(q.Name);
Reply all
Reply to author
Forward
0 new messages