Closed
Description
CBP created an issue — 11th July 2013, 3:40:45:
This issue affects CreateCriteria. I haven't tried it with QueryOver.
Here is a query that demonstrates the problem:
var detachedCriteria2 = DetachedCriteria.For<VehicleFamily>("vf_inner_2") .SetProjection(Projections.Id()) .Add(Restrictions.Eq("mk.Prestige", true)) .Add(Restrictions.EqProperty("vf_inner_2.Id", "vf_inner.Id")); var detachedCriteria1 = DetachedCriteria.For<VehicleFamily>("vf_inner") .SetProjection(Projections.Id()) .Add(Subqueries.Exists(detachedCriteria2)) .Add(Restrictions.EqProperty("vf_inner.Id", "vf.Id")); CurrentSession.CreateCriteria<VehicleFamily>("vf") .CreateAlias("vf.Make", "mk") .AddOrder(Order.Asc(Projections.SubQuery(detachedCriteria1))) .List<VehicleFamily>();
Here's the relevant portion of the mapping, in Fluent NH:
public class VehicleFamilyDbMap : ClassMap<VehicleFamily> { public VehicleFamilyDbMap() { Id(x => x.Id); References(x => x.Make); } } public class VehicleMakeDbMap : ClassMap<VehicleMake> { public VehicleMakeDbMap() { Id(x => x.Id); Map(x => x.Prestige); } }
The error thrown is:
System.ArgumentNullException : Value cannot be null. Parameter name: key at System.Collections.Generic.Dictionary`2.FindEntry(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, ref TValue value) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetPropertyMapping(String entityName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 660 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetType(ICriteria subcriteria, String propertyName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 633 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetTypeUsingProjection(ICriteria subcriteria, String propertyName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 612 at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName(ICriteriaQuery criteriaQuery, ICriteria criteria, String propertyName, Object value, ICriterion critertion) in p:\nhibernate-core\src\NHibernate\Criterion\CriterionUtil.cs: line 76 at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SimpleExpression.cs: line 81 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 201 at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 43 at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryExpression.cs: line 60 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 201 at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 43 at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryExpression.cs: line 60 at NHibernate.Criterion.SubqueryProjection.ToSqlString(ICriteria criteria, Int32 loc, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryProjection.cs: line 46 at NHibernate.Criterion.Order.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) in p:\nhibernate-core\src\NHibernate\Criterion\Order.cs: line 45 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetOrderBy() in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 220 at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 58 at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaLoader.cs: line 41 at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs: line 1938 at NHibernate.Impl.CriteriaImpl.List(IList results) in p:\nhibernate-core\src\NHibernate\Impl\CriteriaImpl.cs: line 265 at NHibernate.Impl.CriteriaImpl.List() in p:\nhibernate-core\src\NHibernate\Impl\CriteriaImpl.cs: line 276
The issue is because we are trying to use the alias "mk" which occurs 2 levels up of nested queries. Note that this should result in perfectly valid SQL.
I would also like to point out that the error thrown is very unfriendly. It would be good to throw a more descriptive error, e.g. "alias 'mk' cannot be found" as debugging this issue is painful.
Kamil Kliczbor added a comment — 16th July 2013, 7:15:01:
Hi, could you provide bug reproduction in JIRA ?