I've been doing a pet project to teach myself nHibernate for the last few weeks with around 20ish entities and tables, including table-per-subclass mappings.
Everything was fine until I added another level to a class hierarchy [not the issue as it turns out].
A list of objects in the class hierarchy began to fail to load, claiming a null reference exception inside nHibernate itself while trying to get the name of a column (or the ordinal of a column by name - I forget which) returned by a datareader.
I've narrowed it down to a simple <many-to-one> reference - comment it out, the entity loads, put it back in, the entity load fails.
All other entities and associations work as expected. Also, the SQL from the resulting query works directly in SQL Server.
Since then, I've pulled a fragment of the project out of the main one and created a small 2 table db to illustrate the problem.
I now have ModellingItem with a <many-to-one> to a Manufacturer. This fails with the information below.
Hibernate version: 1.2.0 beta 2
Mapping documents: In seperate file, shown here as one for clarity:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="field.pascalcase-underscore" namespace="Sleeping" assembly="Sleeping">
<class name="ModellingItem" table="ModellingItem" dynamic-update="true" lazy="false">
<id name="ID" column="ID" type="Int32" unsaved-value="0">
<generator class="identity" />
</id>
<property name="Name" column="Name" type="String" length="50" />
<property name="Notes" column="Notes" type="String" length="500" />
<many-to-one name="Manufacturer" class="Manufacturer" column="Manufacturer" />
</class>
<class name="Manufacturer" table="Manufacturer" dynamic-update="true" lazy="false">
<id name="ID" column="ID" type="Int32" unsaved-value="0">
<generator class="identity" />
</id>
<property name="Name" column="Name" type="String" length="50" />
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
With Session.Current.NHibernate 'My create session
Dim o0 As Manufacturer= DirectCast(.Get(GetType(Manufacturer), 1), Manufacturer)
Dim o1 As ModellingItem= DirectCast(.Get(GetType(ModellingItem), 2), ModellingItem)
.Close()
End With
Full stack trace of any exception that occurs:Code:
{"could not load an entity: [Sleeping.ModellingItem#2][SQL: SELECT modellingi0_.ID as ID1_1_, modellingi0_.Name as Name1_1_, modellingi0_.Notes as Notes1_1_, modellingi0_.Manufacturer as Manufact4_1_1_, manufactur1_.ID as ID0_0_, manufactur1_.Name as Name0_0_ FROM ModellingItem modellingi0_ left outer join Manufacturer manufactur1_ on modellingi0_.Manufacturer=manufactur1_.ID WHERE modellingi0_.ID=?]"}
" at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, Type optionalEntityName, Object optionalIdentifier, IEntityPersister persister) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1487
at NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Entity\AbstractEntityLoader.cs:line 47
at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Entity\AbstractEntityLoader.cs:line 42
at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2424
at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2807
at NHibernate.Impl.SessionImpl.DoLoadByClass(Type clazz, Object id, Boolean checkDeleted, Boolean allowProxyCreation) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2567
at NHibernate.Impl.SessionImpl.Get(Type clazz, Object id) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2477
at Sleeping.Form1.Form1_Load(Object sender, EventArgs e) in D:\Projects\Sleeping\Form1.vb:line 7
<snip>windows app start</snip>
The real problem from the InnerException:
Code:
{"Invalid attempt to MetaData when reader is closed."}
" at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlDataReader.GetOrdinal(String name)
at NHibernate.Driver.NHybridDataReader.GetOrdinal(String name) in c:\net\nhibernate\nhibernate\src\NHibernate\Driver\NHybridDataReader.cs:line 362
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name) in c:\net\nhibernate\nhibernate\src\NHibernate\Type\NullableType.cs:line 253
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner) in c:\net\nhibernate\nhibernate\src\NHibernate\Type\NullableType.cs:line 212
at NHibernate.Type.AbstractType.Hydrate(IDataReader rs, String[] names, ISessionImplementor session, Object owner) in c:\net\nhibernate\nhibernate\src\NHibernate\Type\AbstractType.cs:line 128
at NHibernate.Loader.Loader.Hydrate(IDataReader rs, Object id, Object obj, ILoadable persister, ISessionImplementor session, String[][] suffixedPropertyColumns) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1101
at NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs, Int32 i, Object obj, Type instanceClass, EntityKey key, LockMode lockMode, ILoadable rootPersister, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1000
at NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader dr, Int32 i, ILoadable persister, EntityKey key, LockMode lockMode, EntityKey optionalObjectKey, Object optionalObject, IList hydratedObjects, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 957
at NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, EntityKey[] keys, Object optionalObject, EntityKey optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 891
at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 295
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 424
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 183
at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, Type optionalEntityName, Object optionalIdentifier, IEntityPersister persister) in c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1475"
Name and version of the database you are using:SQL Server 2005
DB Create Script:Code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Manufacturer](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
CONSTRAINT [PK_Manufacturer] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY],
CONSTRAINT [DK_Manufacturer] UNIQUE NONCLUSTERED
(
[Name] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
/****** Object: Table [dbo].[ModellingItem] Script Date: 01/09/2007 14:56:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[ModellingItem](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
[Notes] [varchar](500) COLLATE Latin1_General_CI_AS NOT NULL,
[Manufacturer] [int] NOT NULL,
CONSTRAINT [PK_ModellingItem] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[ModellingItem] WITH CHECK ADD CONSTRAINT [FK_ModellingItem_Manufacturer] FOREIGN KEY([Manufacturer])
REFERENCES [dbo].[Manufacturer] ([ID])