tags:

views:

234

answers:

3

Hello, I am getting the following error when trying to update an object using nhibernate. I am attempting to update a field which is a foreign key. Any thoughts why I might be getting this error? I can't figure it out from that error and my log4net log doesn't give any hints either.

Thanks

    System.IndexOutOfRangeException was unhandled by user code
  Message="Parameter index is out of range."
  Source="MySql.Data"
  StackTrace:
       at MySql.Data.MySqlClient.MySqlParameterCollection.CheckIndex(Int32 index)
       at MySql.Data.MySqlClient.MySqlParameterCollection.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.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index)
       at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
       at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
       at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
       at NHibernate.Action.EntityUpdateAction.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 NHibernate.Transaction.AdoTransaction.Commit()
       at DataAccessLayer.NHibernateDataProvider.UpdateItem_temp(items_temp item_temp) in C:\Documents and Settings\user\My Documents\Visual Studio 2008\Projects\mySolution\DataAccessLayer\NHibernateDataProvider.cs:line 225
       at InventoryDataClean.Controllers.ImportController.Edit(Int32 id, FormCollection formValues) in C:\Documents and Settings\user\My Documents\Visual Studio 2008\Projects\mySolution\InventoryDataClean\Controllers\ImportController.cs:line 101
       at lambda_method(ExecutionScope , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: 

Here is my item mapping -

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
  <class name="DataTransfer.items_temp, DataTransfer" table="items_temp">
    <id name="id" unsaved-value="any" >
      <generator class="assigned"/>
    </id>
    <property name="assetid"/>
    <property name="description"/>
    <property name="caretaker"/>
    <property name="category"/>
    <property name="status"  />
    <property name="vendor" />

    <many-to-one name="statusName" class="status" column="status" />
  </class>
</hibernate-mapping>

Here is my status mapping -

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
  <class name="DataTransfer.status, DataTransfer" table="status">
    <id name="id" unsaved-value="0">
      <generator class="assigned"/>
    </id>
    <property name="name"/>
    <property name="def"/>

  </class>
</hibernate-mapping>

and here is my update function -

public void UpdateItem_temp(items_temp item_temp)
        {
            ITransaction t = _session.BeginTransaction();
            try
            {
                _session.SaveOrUpdate(item_temp);
                t.Commit();
            }
            catch (Exception)
            {
                t.Rollback();
                throw;
            }
            finally
            {
                t.Dispose();
            }
        }
A: 

This could be due to the order in which NHibernate is attempting to save data to the database. I would suspect that it is because it is trying to set the foreign key id in the main table before the foreign key entry is in the referenced table. It would help if you post your mappings and data schema, as well as the code for assigning and saving the property

Daniel Dyson
I am not actually adding a new item to the foreign table. that is a static table - it holds different status values with an integer id that acts as the pk. then in the item table, there is a status field that relates back to the status table.In the mean time, I will post my mappings.Thanks
czuroski
-1 That only occurs when you set the FK column to Not Nullable.
David Kemp
David - Good point, but not fair to down vote me because he hadn't added any code when I added my answer. Without the mapping information, my answer was valid, and I did ask czuroski to add the mappings to the question, so I think my reply did contribute.
Daniel Dyson
A: 

I've encountered an exception that looks like this before when trying to save or update an entity with a mismatch between the mappings and the table; specifically when a column name has been misspelled or the column exists only in one of the two locations.

Kevin Gorski
+1  A: 

You mapped the items_temp.status twice - once as a property and once as a many-to-one reference.

<property name="status"  />
<many-to-one name="statusName" class="status" column="status" />

If you want to do this, you need to change the column name of one of these.

David Kemp
I thought by changing the name to statusName, I was doing it correctly. I then just have to change the column?
czuroski
No - it will use the property name and as the column name - if you genuinely have a property called "status" and a property called "statusName", then you need to have two columns. What I suspect you have is one property - so you just need the M-to-1 mapping.
David Kemp
status is the field in the item table that holds the id which relates back to the status table. I'm not sure how I would change the mapping.
czuroski
You should map the relationship to the Status object.
Jamie Ide
just delete the <property> line - set the name of statusName to status
David Kemp
thanks - I will try that out.
czuroski
Now I am getting another error when attempting to update the model - NHibernate.HibernateException was unhandled by user code Message="identifier of an instance of DataTransfer.status was altered from 3 to 6"
czuroski
How are you assigning your status? You can't just change the id, you have to actually assign the whole status object.
David Kemp