ICriteria query on IUserType property

184 views
Skip to first unread message

HappyNomad

unread,
Aug 6, 2011, 4:40:16 PM8/6/11
to nhibernate-development
I am posting this to nh-dev instead of nh-users since I got my code
working, and am just wondering if some NH code needs corrected or not.

I mapped a System.Uri property called "URL" to an nvarchar column
using the "UriType" IUserType posted here:
http://intellect.dk/post/Implementing-custom-types-in-nHibernate.aspx

I then created an ICriteria query:

return session.CreateCriteria<Bookmark>()
.Add( Expression.Like("URL", "file:%" )
.List<Bookmark>();

To my surprise, the above List() call causes an exception to be
thrown:

NHibernate.QueryException was unhandled by user code
Message=Type mismatch in NHibernate.Criterion.SimpleExpression: URL
expected type System.Uri, actual type System.String
Source=NHibernate
StackTrace:
at
NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName(ICriteriaQuery
criteriaQuery, ICriteria criteria, String propertyName, Object value,
ICriterion critertion)
at
NHibernate.Criterion.CriterionUtil.GetColumnNamesForSimpleExpression(String
propertyName, IProjection projection, ICriteriaQuery criteriaQuery,
ICriteria criteria, IDictionary`2 enabledFilters, ICriterion
criterion, Object value)
at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria
criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters)
at
NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2
enabledFilters)
at
NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable
persister, CriteriaQueryTranslator translator,
ISessionFactoryImplementor factory, ICriteria criteria, String
rootEntityName, IDictionary`2 enabledFilters)
at
NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable
persister, ISessionFactoryImplementor factory, CriteriaImpl
rootCriteria, String rootEntityName, IDictionary`2 enabledFilters)
at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria,
IList results)
at NHibernate.Impl.CriteriaImpl.List(IList results)
at NHibernate.Impl.CriteriaImpl.List[T]()

The NH source code that threw the exception looks like this:

if (value != null && !(value is System.Type) && !
propertyType.ReturnedClass.IsInstanceOfType(value))
{
throw new QueryException(string.Format(
"Type mismatch in {0}: {1} expected type {2}, actual type {3}",
critertion.GetType(), propertyName, propertyType.ReturnedClass,
value.GetType()));
}

I got my code working by changing it like this:

return session.CreateCriteria<Bookmark>()
.Add( Expression.Like("URL", new Uri("file:%", UriKind.Relative)) )
.List<Bookmark>();

But I'm thinking that maybe NH should not have thrown that exception
to begin with. Would anyone else support this idea? Or, if it is
working exactly like it should, then please explain.

Fabio Maulo

unread,
Aug 7, 2011, 8:50:05 AM8/7/11
to nhibernate-...@googlegroups.com
- The Uri is natively supported by NHibernate

- Criteria using LIKE works: s.CreateCriteria<UriClass>().Add(Restrictions.Like("Url", "fabio", MatchMode.Anywhere)).UniqueResult<UriClass>();

- HQL works: s.CreateQuery("from UriClass u where u.Url = :pUrl").SetParameter("pUrl", new Uri("http://fabiomaulo.blogspot.com/2010/10/nhibernate-30-cookbook.html")).UniqueResult<UriClass>();

- Criteria using Equals works: s.CreateCriteria<UriClass>().Add(Restrictions.Eq("Url", new Uri("http://fabiomaulo.blogspot.com/2010/10/nhibernate-30-cookbook.html"))).UniqueResult<UriClass>();

- Query over works: s.QueryOver<UriClass>().Where(x => x.Url == new Uri("http://fabiomaulo.blogspot.com/2010/10/nhibernate-30-cookbook.html")).SingleOrDefault<UriClass>();

- LINQ works : s.Query<UriClass>().Where(x => x.Url == new Uri("http://fabiomaulo.blogspot.com/2010/10/nhibernate-30-cookbook.html")).SingleOrDefault();

This is the group for dev-team, if you need this kind of help please use the nhusers group.
Thanks.
--
Fabio Maulo

HappyNomad

unread,
Aug 7, 2011, 9:50:42 AM8/7/11
to nhibernate-development
Thanks for the code samples, Fabio. But I just tried the ICriteria
one, which is close to my original attempt, and it still threw the
exception I mentioned. That is, the URI fragment still needs to be
wrapped in a Uri instance, which seems wrong to me. You said that
"Uri is natively supported by NHibernate". Was such support added in
NH3? I'm still using NH v2.1.2 so wouldn't have noticed this. So in
NH3 is the "UriType" IUserType that I linked to not needed when
mapping a System.Uri property to an nvarchar column?

Fabio Maulo

unread,
Aug 7, 2011, 10:03:22 AM8/7/11
to nhibernate-...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages