nHibernate 2
HBM.xml mapping
<list name="Fields" fetch="join" cascade="all-delete-orphan" lazy="false">
<key column="ViewID" foreign-key="fk_ViewID"></key>
<index column="fieldorder" />
<one-to-many class="Field"/>
</list>
Code in the session using (ISession session = PersistenceSession.NewSession)
{
using (ITransaction transaction = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(obj);
session.Flush();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw new Exception("An error has occurred : " + ex.Message, ex);
}
}
}
Full stack trace of any exception that occurs:
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.Collections.ArrayList.get_Item(Int32 index)
at Oracle.DataAccess.Client.OracleParameterCollection.GetParameter(Int32 index)
at System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index)
at NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index)
at NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index)
at NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, ISessionImplementor session)
at NHibernate.Persister.Collection.AbstractCollectionPersister.WriteKey(IDbCommand st, Object id, Int32 i, ISessionImplementor session)
at NHibernate.Persister.Collection.AbstractCollectionPersister.InsertRows(IPersistentCollection collection, Object id, ISessionImplementor session)
at NHibernate.Action.CollectionUpdateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at Persistence.Repository.Save(Object obj) in Repository.cs: line 49
Name and version of the database you are using : Oracle 10g with the ODP drivers.
There is no issue if I use the Oracle drivers from microsoft. Also no issue if I use SQL Server instead.
To recreate, I populate the collection, then save the parent.
Get the parent back from the database, then call .Clear; on the collection, and resave the parent. ie
View view = new View();
IField field = Factory.NewField("test" + Guid.NewGuid());
view.fields.add(field);
Repository.Save(view);
View viewFromDB = Repository.GetView(view.ID);
viewFromDB .fields.Clear();
IField field2 = Factory.NewField("test" + Guid.NewGuid());
viewFromDB.fields.add(field);
viewFromDB.fields.add(field2);
Repository.Save(viewFromDB);
The problem seems to be with the dispose method of the oracleCommand object clearing the parameters collection, but I'm no expert.
I can work around it by clearing the collection, saving, then adding more items, but this isn't satisfactory.
Any ideas?
|