I apologize in advance if this has already been covered. I wasn't able to find anything when I searched the forums, though... so here goes.
Here's a summary of the problem that I'm encountering. I have a mapping for Kennel. Kennel has two properties derived from formulas, ReviewCount and RatingScore. When I attempt to load a Kennel by id, it works fine and the SQL looks as I would expect it.
However, when I attempt to load a list from a named query, I receive the error "value cannot be null. Parameter name: fieldName". Stepping through the code shows me that the NHibernate loader is passing a null column name into the data reader.
I originally did not specify a column name for the derived property mapping. I have since added the column names and ensured they match the column names for the formulas on my named query. I assume I've botched something up in the middle somewhere...
Hibernate version:
NHibernate 1.2.0.4
Mapping documents:
Here is a (slightly trimmed down, removed the bags) copy of the mapping document:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
<class name="KennelFinder.Kennel, KennelFinder" table="Kennel">
<id name="Id" type="Int32" access="nosetter.camelcase" >
<column name="kennelId" not-null="true" unique="true" />
<generator class="native" />
</id>
<version name="Version" column="version" access="nosetter.camelcase" />
<property name="Name" column="Name" />
<property name="Address1" column="Address1" />
<property name="Address2" column="Address2" />
<property name="City" column="City" />
<property name="State" column="State" />
<property name="ZipCode" column="postal" />
<property name="InsertDate" column="InsertDate" />
<property name="LastUpdateDate" column="LastUpdateDate" />
<property name="LastEmailNotice" column="LastEmailNotice" />
<property name="SearchRank" column="SearchRank" />
<property name="IsAbkaMember" column="abkaMember" />
<property name="Status" column="Status" type="KennelFinder.KennelStatus, KennelFinder" />
<property name="IsVerified" column="IsVerified" />
<property name="ReviewCount" column="ReviewCount" formula="(select count(r.kennelid) from rating r where r.kennelid = kennelId)" update="false" insert="false"></property>
<property name="RatingScore" column="RatingScore" formula="isnull((select avg(r.rating) from rating r where r.kennelid = kennelId),0)" update="false" insert="false"></property>
</class>
<sql-query name="GetKennelListByVicinity">
<return alias="Kennels" class="KennelFinder.Kennel, KennelFinder" lock-mode="none" />
<![CDATA[
SET NOCOUNT ON;
declare @zipcode char(5)
declare @latitude decimal(9,6)
declare @longitude decimal(9,6)
create table #zipCodes (zipcode char(5))
DECLARE ZipCode_Cursor CURSOR LOCAL FAST_FORWARD FOR
select zipcode, latitude, longitude from geoinformation where city = :city and statecode = :state
open ZipCode_Cursor
fetch next from ZipCode_Cursor
into @zipcode, @latitude, @longitude
while @@FETCH_STATUS = 0
begin
insert into #zipCodes values (@zipCode)
insert #zipCodes
select distinct zipCode from geoinformation g, radius(@latitude, @longitude, :radius) rad
where g.latitude >= rad.minLatitude and g.latitude <= rad.maxLatitude and g.longitude >= rad.minLongitude and g.longitude <= rad.maxLongitude
fetch next from ZipCode_Cursor
into @zipcode, @latitude, @longitude
end
close ZipCode_Cursor
deallocate ZipCode_Cursor
SELECT k.*,
(select count(r.kennelid) from rating r where r.kennelid = k.kennelId) as ReviewCount,
isnull((select avg(r.rating) from rating r where r.kennelid = k.kennelId),0) as RatingScore
FROM [mobyWeb].[dbo].[Kennel] k
where
k.postal in (select distinct zipcode from #zipcodes)
order by
k.name
drop table #zipCodes
]]>
</sql-query>
</hibernate-mapping>
The two lines I believe to be the offending lines are:
Code:
<property name="ReviewCount" column="ReviewCount" formula="(select count(r.kennelid) from rating r where r.kennelid = kennelId)" update="false" insert="false"></property>
<property name="RatingScore" column="RatingScore" formula="isnull((select avg(r.rating) from rating r where r.kennelid = kennelId),0)" update="false" insert="false"></property>
The code that calls this is:
Code:
public static List<Kennel> FindByCityVicinity(string city, string state, short radius)
{
IQuery vicinityQuery = DbSessionContext.Current.Session.GetNamedQuery("GetKennelListByVicinity");
vicinityQuery.SetString("city", city);
vicinityQuery.SetString("state", state);
vicinityQuery.SetInt16("radius", radius);
return vicinityQuery.List<Kennel>() as List<Kennel>;
}
Full stack trace of any exception that occurs:Code:
[ArgumentNullException: Value cannot be null.
Parameter name: fieldName]
System.Data.ProviderBase.FieldNameLookup.GetOrdinal(String fieldName) +1360553
System.Data.SqlClient.SqlDataReader.GetOrdinal(String name) +102
NHibernate.Driver.NHybridDataReader.GetOrdinal(String name) +10
NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name) +33
NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner) +25
NHibernate.Type.AbstractType.Hydrate(IDataReader rs, String[] names, ISessionImplementor session, Object owner) +19
NHibernate.Loader.Loader.Hydrate(IDataReader rs, Object id, Object obj, ILoadable persister, ISessionImplementor session, String[][] suffixedPropertyColumns) +227
NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs, Int32 i, Object obj, Type instanceClass, EntityKey key, LockMode lockMode, ILoadable rootPersister, ISessionImplementor session) +224
NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader dr, Int32 i, ILoadable persister, EntityKey key, LockMode lockMode, EntityKey optionalObjectKey, Object optionalObject, IList hydratedObjects, ISessionImplementor session) +153
NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, EntityKey[] keys, Object optionalObject, EntityKey optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session) +271
NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) +178
NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +496
NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +56
NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +29
[ADOException: could not execute query
[ SET NOCOUNT ON;
declare @zipcode char(5)
declare @latitude decimal(9,6)
declare @longitude decimal(9,6)
create table #zipCodes (zipcode char(5))
DECLARE ZipCode_Cursor CURSOR LOCAL FAST_FORWARD FOR
select zipcode, latitude, longitude from geoinformation where city = ? and statecode = ?
open ZipCode_Cursor
fetch next from ZipCode_Cursor
into @zipcode, @latitude, @longitude
while @@FETCH_STATUS = 0
begin
insert into #zipCodes values (@zipCode)
insert #zipCodes
select distinct zipCode from geoinformation g, radius(@latitude, @longitude, ?) rad
where g.latitude >= rad.minLatitude and g.latitude <= rad.maxLatitude and g.longitude >= rad.minLongitude and g.longitude <= rad.maxLongitude
fetch next from ZipCode_Cursor
into @zipcode, @latitude, @longitude
end
close ZipCode_Cursor
deallocate ZipCode_Cursor
SELECT k.*,
(select count(r.kennelid) from rating r where r.kennelid = k.kennelId) as ReviewCount,
isnull((select avg(r.rating) from rating r where r.kennelid = k.kennelId),0) as RatingScore
FROM [mobyWeb].[dbo].[Kennel] k
where
k.postal in (select distinct zipcode from #zipcodes)
order by
k.name
drop table #zipCodes ]
Name: state - Value: MN
Name: radius - Value: 25
Name: city - Value: Eden Prairie
[SQL: SET NOCOUNT ON;
declare @zipcode char(5)
declare @latitude decimal(9,6)
declare @longitude decimal(9,6)
create table #zipCodes (zipcode char(5))
DECLARE ZipCode_Cursor CURSOR LOCAL FAST_FORWARD FOR
select zipcode, latitude, longitude from geoinformation where city = ? and statecode = ?
open ZipCode_Cursor
fetch next from ZipCode_Cursor
into @zipcode, @latitude, @longitude
while @@FETCH_STATUS = 0
begin
insert into #zipCodes values (@zipCode)
insert #zipCodes
select distinct zipCode from geoinformation g, radius(@latitude, @longitude, ?) rad
where g.latitude >= rad.minLatitude and g.latitude <= rad.maxLatitude and g.longitude >= rad.minLongitude and g.longitude <= rad.maxLongitude
fetch next from ZipCode_Cursor
into @zipcode, @latitude, @longitude
end
close ZipCode_Cursor
deallocate ZipCode_Cursor
SELECT k.*,
(select count(r.kennelid) from rating r where r.kennelid = k.kennelId) as ReviewCount,
isnull((select avg(r.rating) from rating r where r.kennelid = k.kennelId),0) as RatingScore
FROM [mobyWeb].[dbo].[Kennel] k
where
k.postal in (select distinct zipcode from #zipcodes)
order by
k.name
drop table #zipCodes]]
NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +109
NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes) +78
NHibernate.Impl.SessionImpl.ListCustomQuery(ICustomQuery customQuery, QueryParameters queryParameters, IList results) +99
NHibernate.Impl.SessionImpl.List(NativeSQLQuerySpecification spec, QueryParameters queryParameters) +136
NHibernate.Impl.SqlQueryImpl.List() +214
KennelFinder.KennelDataAccess.FindByCityVicinity(String city, String state, Int16 radius) in C:\oms\KennelFinder\src\KennelFinder\KennelDataAccess.cs:29
KennelFinder.Web.SearchResults.ShowResultList(String address, String city, String state, Int16 radius, Double latitude, Double longitude) in C:\oms\KennelFinder\src\KennelFinder.Web\SearchResults.aspx.cs:67
KennelFinder.Web.SearchResults.Page_Load(Object sender, EventArgs e) in C:\oms\KennelFinder\src\KennelFinder.Web\SearchResults.aspx.cs:59
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061
Again, adding in the NHibernate source and stepping through, the issue comes down to the fact that, somehow, a null column name is being passed in to the data reader. I think I've isolated it to the two formula mappings because everything works fine when I comment those two lines out of my mapping document.
Name and version of the database you are using:
SQL Server 2005 with the SQL Server 2005 dialect