Parent-Child with bidirectional cascade - "save-update" at the child and "all-delete-orphan" at the parent.
NHibernate.Collection.AbstractPersistentCollection.GetOrphans() tries to add a null key to the dict.
Hibernate version: 1.2.1GA and 1.2.0GA (happens in both versions)
Mapping documents:
Code:
<class name="Child" table="Children">
<id name="Id" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Name" type="String"/>
<many-to-one name="Parent" column="ParentId" class="Parent" cascade="save-update" not-null="true"/>
</class>
<class name="Parent" table="Parents">
<id name="Id" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Name" type="String"/>
<set name="Children" inverse="true" cascade="all-delete-orphan" lazy="true" optimistic-lock="false"
>
<key column="ParentId" />
<one-to-many class="Child" />
</set>
</class>
Code between sessionFactory.openSession() and session.close():Code:
var p = new Parent() {Name = "P1"};
var c0 = new Child() {Parent = p, Name = "C0"};
p.Children.Add(c0);
session.Save(c0);
Full stack trace of any exception that occurs:The exception occurs at "session.Save(c0)".
See the log below for a stack trace and exception messages.
Name and version of the database you are using:SQL Server 2005
The generated SQL (show_sql=true):Code:
NHibernate: INSERT INTO Parents (Name) VALUES (@p0); select SCOPE_IDENTITY(); @p
0 = 'P1'
Debug level Hibernate log excerpt:Code:
2008-05-20 17:00:58,114 Thread-1 INFO NHibernate.Cfg.Environment: NHibernate 1.2.1.4000 (1.2.1.4000)
2008-05-20 17:00:58,146 Thread-1 INFO NHibernate.Cfg.Environment: nhibernate section not found in application configuration file
2008-05-20 17:00:58,146 Thread-1 INFO NHibernate.Cfg.Environment: Bytecode provider name : lcg
2008-05-20 17:00:58,146 Thread-1 INFO NHibernate.Cfg.Environment: Using reflection optimizer
2008-05-20 17:00:58,177 Thread-1 DEBUG NHibernate.Cfg.Configuration: dialect=NHibernate.Dialect.MsSql2005Dialect
2008-05-20 17:00:58,177 Thread-1 DEBUG NHibernate.Cfg.Configuration: connection.provider=NHibernate.Connection.DriverConnectionProvider
2008-05-20 17:00:58,177 Thread-1 DEBUG NHibernate.Cfg.Configuration: connection.driver_class=NHibernate.Driver.SqlClientDriver
2008-05-20 17:00:58,177 Thread-1 DEBUG NHibernate.Cfg.Configuration: connection.connection_string=Data Source=localhost\SQLEXPRESS;Initial Catalog=NHibTest;Integrated Security=SSPI
2008-05-20 17:00:58,177 Thread-1 DEBUG NHibernate.Cfg.Configuration: hibernate.show_sql=true
2008-05-20 17:00:58,177 Thread-1 DEBUG NHibernate.Cfg.Configuration: <-NHibParentChild
2008-05-20 17:00:58,177 Thread-1 INFO NHibernate.Cfg.Configuration: Searching for mapped documents in assembly: NHibParentChild
2008-05-20 17:00:58,177 Thread-1 INFO NHibernate.Cfg.Configuration: Mapping resource: NHibParentChild.ent.hbm.xml
2008-05-20 17:00:58,240 Thread-1 INFO NHibernate.Dialect.Dialect: Using dialect: NHibernate.Dialect.MsSql2005Dialect
2008-05-20 17:00:58,271 Thread-1 INFO NHibernate.Cfg.HbmBinder: Mapping class: NHibParentChild.Child -> Children
2008-05-20 17:00:58,302 Thread-1 DEBUG NHibernate.Cfg.HbmBinder: Mapped property: Id -> Id, type: Int32
2008-05-20 17:00:58,318 Thread-1 DEBUG NHibernate.Cfg.HbmBinder: Mapped property: Name -> Name, type: String
2008-05-20 17:00:58,334 Thread-1 DEBUG NHibernate.Cfg.HbmBinder: Mapped property: Parent -> ParentId, type: Parent
2008-05-20 17:00:58,334 Thread-1 INFO NHibernate.Cfg.HbmBinder: Mapping class: NHibParentChild.Parent -> Parents
2008-05-20 17:00:58,334 Thread-1 DEBUG NHibernate.Cfg.HbmBinder: Mapped property: Id -> Id, type: Int32
2008-05-20 17:00:58,334 Thread-1 DEBUG NHibernate.Cfg.HbmBinder: Mapped property: Name -> Name, type: String
2008-05-20 17:00:58,365 Thread-1 DEBUG NHibernate.Cfg.HbmBinder: Mapped property: Children, type: ISet`1
2008-05-20 17:00:58,365 Thread-1 DEBUG NHibernate.Cfg.Configuration: properties: System.Collections.Hashtable
2008-05-20 17:00:58,365 Thread-1 INFO NHibernate.Cfg.Configuration: checking mappings queue
2008-05-20 17:00:58,365 Thread-1 INFO NHibernate.Cfg.Configuration: processing one-to-many association mappings
2008-05-20 17:00:58,365 Thread-1 DEBUG NHibernate.Cfg.CollectionSecondPass: Second pass for collection: NHibParentChild.Parent.Children
2008-05-20 17:00:58,365 Thread-1 INFO NHibernate.Cfg.HbmBinder: mapping collection: NHibParentChild.Parent.Children -> Children
2008-05-20 17:00:58,365 Thread-1 DEBUG NHibernate.Cfg.CollectionSecondPass: Mapped collection key: ParentId, one-to-many: Child
2008-05-20 17:00:58,365 Thread-1 INFO NHibernate.Cfg.Configuration: processing one-to-one association property references
2008-05-20 17:00:58,365 Thread-1 INFO NHibernate.Cfg.Configuration: processing foreign key constraints
2008-05-20 17:00:58,365 Thread-1 DEBUG NHibernate.Cfg.Configuration: resolving reference to class: Parent
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Dialect.Dialect: Using dialect: NHibernate.Dialect.MsSql2005Dialect
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Connection.ConnectionProviderFactory: Initializing connection provider: NHibernate.Connection.DriverConnectionProvider
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Connection.ConnectionProvider: Configuring ConnectionProvider
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Cfg.SettingsFactory: Transaction factory: NHibernate.Transaction.AdoNetTransactionFactory
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Cfg.SettingsFactory: Optimize cache for minimal puts: False
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Cfg.SettingsFactory: Connection release mode: auto
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Cfg.SettingsFactory: echoing all SQL to stdout
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Cfg.SettingsFactory: Query translator: NHibernate.Hql.Classic.ClassicQueryTranslatorFactory
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Cfg.SettingsFactory: Query language substitutions: {}
2008-05-20 17:00:58,396 Thread-1 INFO NHibernate.Cfg.SettingsFactory: cache provider: NHibernate.Cache.NoCacheProvider, NHibernate, Version=1.2.1.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4
2008-05-20 17:00:58,412 Thread-1 INFO NHibernate.Impl.SessionFactoryImpl: building session factory
2008-05-20 17:00:58,412 Thread-1 DEBUG NHibernate.Impl.SessionFactoryImpl: instantiating session factory with properties: {hibernate.dialect=NHibernate.Dialect.MsSql2005Dialect, hibernate.connection.connection_string=Data Source=localhost\SQLEXPRESS;Initial Catalog=NHibTest;Integrated Security=SSPI, dialect=NHibernate.Dialect.MsSql2005Dialect, connection.driver_class=NHibernate.Driver.SqlClientDriver, hibernate.connection.driver_class=NHibernate.Driver.SqlClientDriver, hibernate.show_sql=true, hibernate.use_reflection_optimizer=true, connection.connection_string=Data Source=localhost\SQLEXPRESS;Initial Catalog=NHibTest;Integrated Security=SSPI, connection.provider=NHibernate.Connection.DriverConnectionProvider, hibernate.connection.provider=NHibernate.Connection.DriverConnectionProvider}
2008-05-20 17:00:58,553 Thread-1 DEBUG NHibernate.Impl.SessionFactoryObjectFactory: initializing class SessionFactoryObjectFactory
2008-05-20 17:00:58,553 Thread-1 DEBUG NHibernate.Impl.SessionFactoryObjectFactory: registered: 0fb4efdea3ba4b7bb2758156523b12c7(unnamed)
2008-05-20 17:00:58,553 Thread-1 INFO NHibernate.Impl.SessionFactoryObjectFactory: no name configured
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Parent: SELECT parent0_.Id as Id1_0_, parent0_.Name as Name1_0_ FROM Parents parent0_ WHERE parent0_.Id=?
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Parent: SELECT parent0_.Id as Id1_0_, parent0_.Name as Name1_0_ FROM Parents parent0_ WHERE parent0_.Id=?
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Parent: SELECT parent0_.Id as Id1_0_, parent0_.Name as Name1_0_ FROM Parents parent0_ with (updlock, rowlock) WHERE parent0_.Id=?
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Parent: SELECT parent0_.Id as Id1_0_, parent0_.Name as Name1_0_ FROM Parents parent0_ with (updlock, rowlock) WHERE parent0_.Id=?
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Child: SELECT child0_.Id as Id0_0_, child0_.Name as Name0_0_, child0_.ParentId as ParentId0_0_ FROM Children child0_ WHERE child0_.Id=?
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Child: SELECT child0_.Id as Id0_0_, child0_.Name as Name0_0_, child0_.ParentId as ParentId0_0_ FROM Children child0_ WHERE child0_.Id=?
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Child: SELECT child0_.Id as Id0_0_, child0_.Name as Name0_0_, child0_.ParentId as ParentId0_0_ FROM Children child0_ with (updlock, rowlock) WHERE child0_.Id=?
2008-05-20 17:00:58,631 Thread-1 DEBUG NHibernate.Loader.Entity.AbstractEntityLoader: Static select for entity NHibParentChild.Child: SELECT child0_.Id as Id0_0_, child0_.Name as Name0_0_, child0_.ParentId as ParentId0_0_ FROM Children child0_ with (updlock, rowlock) WHERE child0_.Id=?
2008-05-20 17:00:58,647 Thread-1 DEBUG NHibernate.Loader.Collection.OneToManyLoader: Static select for one-to-many NHibParentChild.Parent.Children: SELECT children0_.ParentId as ParentId__1_, children0_.Id as Id1_, children0_.Id as Id0_0_, children0_.Name as Name0_0_, children0_.ParentId as ParentId0_0_ FROM Children children0_ WHERE children0_.ParentId=?
2008-05-20 17:00:58,647 Thread-1 DEBUG NHibernate.Impl.SessionFactoryImpl: Instantiated session factory
2008-05-20 17:00:58,663 Thread-1 DEBUG NHibernate.Impl.SessionImpl: opened session
2008-05-20 17:00:58,663 Thread-1 DEBUG NHibernate.Connection.DriverConnectionProvider: Obtaining IDbConnection from Driver
2008-05-20 17:00:59,054 Thread-1 DEBUG NHibernate.Impl.SessionImpl: running ISession.Dispose()
2008-05-20 17:00:59,054 Thread-1 DEBUG NHibernate.Impl.SessionImpl: closing session
2008-05-20 17:00:59,054 Thread-1 DEBUG NHibernate.Impl.BatcherImpl: running BatcherImpl.Dispose(true)
2008-05-20 17:00:59,054 Thread-1 DEBUG NHibernate.Connection.ConnectionProvider: Closing connection
2008-05-20 17:00:59,070 Thread-1 DEBUG NHibernate.Impl.SessionImpl: transaction completion
2008-05-20 17:00:59,070 Thread-1 DEBUG NHibernate.Impl.SessionImpl: opened session
2008-05-20 17:00:59,086 Thread-1 DEBUG NHibernate.Impl.SessionImpl: saving [NHibParentChild.Child#<null>]
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Engine.Cascades: processing cascades for: NHibParentChild.Child
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Engine.Cascades: cascading to SaveOrUpdate()
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Engine.Cascades: unsaved-value: 0
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Impl.SessionImpl: SaveOrUpdate() unsaved instance
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Impl.SessionImpl: saving [NHibParentChild.Parent#<null>]
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Engine.Cascades: processing cascades for: NHibParentChild.Parent
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Engine.Cascades: done processing cascades for: NHibParentChild.Parent
2008-05-20 17:00:59,101 Thread-1 DEBUG NHibernate.Impl.SessionImpl: executing insertions
2008-05-20 17:00:59,117 Thread-1 DEBUG NHibernate.Impl.WrapVisitor: Wrapped collection in role: NHibParentChild.Parent.Children
2008-05-20 17:00:59,133 Thread-1 DEBUG NHibernate.Persister.Entity.AbstractEntityPersister: Inserting entity: NHibParentChild.Parent (native id)
2008-05-20 17:00:59,133 Thread-1 DEBUG NHibernate.Impl.BatcherImpl: Opened new IDbCommand, open IDbCommands: 1
2008-05-20 17:00:59,133 Thread-1 DEBUG NHibernate.Impl.BatcherImpl: Building an IDbCommand object for the SqlString: INSERT INTO Parents (Name) VALUES (?); select SCOPE_IDENTITY()
2008-05-20 17:00:59,133 Thread-1 DEBUG NHibernate.Persister.Entity.AbstractEntityPersister: Dehydrating entity: [NHibParentChild.Parent#<null>]
2008-05-20 17:00:59,133 Thread-1 DEBUG NHibernate.Type.StringType: binding 'P1' to parameter: 0
2008-05-20 17:00:59,133 Thread-1 DEBUG NHibernate.SQL: INSERT INTO Parents (Name) VALUES (@p0); select SCOPE_IDENTITY(); @p0 = 'P1'
2008-05-20 17:00:59,133 Thread-1 DEBUG NHibernate.Connection.DriverConnectionProvider: Obtaining IDbConnection from Driver
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Impl.BatcherImpl: Opened IDataReader, open IDataReaders: 1
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Type.Int32Type: returning '117' as column:
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Persister.Entity.AbstractEntityPersister: Natively generated identity: 117
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Driver.NHybridDataReader: running NHybridDataReader.Dispose()
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Impl.BatcherImpl: Closed IDataReader, open IDataReaders :0
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Impl.BatcherImpl: Closed IDbCommand, open IDbCommands: 0
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Impl.ConnectionManager: aggressively releasing database connection
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Connection.ConnectionProvider: Closing connection
2008-05-20 17:00:59,148 Thread-1 DEBUG NHibernate.Engine.Cascades: processing cascades for: NHibParentChild.Parent
2008-05-20 17:00:59,164 Thread-1 DEBUG NHibernate.Engine.Cascades: cascading to collection: NHibParentChild.Parent.Children
2008-05-20 17:00:59,164 Thread-1 DEBUG NHibernate.Engine.Cascades: cascading to SaveOrUpdate()
2008-05-20 17:00:59,164 Thread-1 DEBUG NHibernate.Impl.SessionImpl: SaveOrUpdate() persistent instance
2008-05-20 17:00:59,164 Thread-1 DEBUG NHibernate.Util.ADOExceptionReporter: Could not save object
System.ArgumentNullException: Key cannot be null.
Parameter name: key
at System.Collections.Hashtable.get_Item(Object key)
at Iesi.Collections.DictionarySet.Add(Object o)
at NHibernate.Collection.AbstractPersistentCollection.GetOrphans(ICollection oldElements, ICollection currentElements, ISessionImplementor session)
at NHibernate.Collection.Generic.PersistentGenericSet`1.GetOrphans(Object snapshot, Type entityName)
at NHibernate.Impl.CollectionEntry.GetOrphans(Type entityName, IPersistentCollection collection)
at NHibernate.Engine.Cascades.DeleteOrphans(Type entityName, IPersistentCollection pc, ISessionImplementor session)
at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything)
at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything)
at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything)
at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything)
2008-05-20 17:00:59,180 Thread-1 WARN NHibernate.Util.ADOExceptionReporter: System.ArgumentNullException: Key cannot be null.
Parameter name: key
at System.Collections.Hashtable.get_Item(Object key)
at Iesi.Collections.DictionarySet.Add(Object o)
at NHibernate.Collection.AbstractPersistentCollection.GetOrphans(ICollection oldElements, ICollection currentElements, ISessionImplementor session)
at NHibernate.Collection.Generic.PersistentGenericSet`1.GetOrphans(Object snapshot, Type entityName)
at NHibernate.Impl.CollectionEntry.GetOrphans(Type entityName, IPersistentCollection collection)
at NHibernate.Engine.Cascades.DeleteOrphans(Type entityName, IPersistentCollection pc, ISessionImplementor session)
at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything)
at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything)
at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything)
at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything)
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything)
2008-05-20 17:00:59,180 Thread-1 ERROR NHibernate.Util.ADOExceptionReporter: Key cannot be null.
Parameter name: key
2008-05-20 17:01:00,260 Thread-1 DEBUG NHibernate.Impl.SessionImpl: running ISession.Dispose()
2008-05-20 17:01:00,260 Thread-1 DEBUG NHibernate.Impl.SessionImpl: closing session
2008-05-20 17:01:00,260 Thread-1 DEBUG NHibernate.Impl.BatcherImpl: running BatcherImpl.Dispose(true)
2008-05-20 17:01:00,260 Thread-1 DEBUG NHibernate.Transaction.AdoTransaction: running AdoTransaction.Dispose()