Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
874 views
in Technique[技术] by (71.8m points)

exception - IndexOutOfRangeException Deep in the bowels of NHibernate

I have the following mappings:

public class SecurityMap : ClassMap<Security>
    {
        public SecurityMap()
        {
            Table("Security");
            CompositeId().KeyProperty(k => k.Id, "SecurityId").KeyProperty(k => k.EndDate);
            Map(x => x.LastUpdateUser);
            References(x => x.Company).Columns("CompanyId", "EndDate");
            References(x => x.PrimaryListing).Columns("PrimaryListingId", "EndDate");
         }
    }

public class ListingMap : ClassMap<Listing>
    {
        public ListingMap()
        {
            Table("Listing");
            CompositeId().KeyProperty(k => k.Id, "ListingID").KeyProperty(k => k.EndDate);
            References(x => x.Security).Columns("SecurityId","EndDate");
        }
    }

 public class CompanyMap : ClassMap<Company>
    {
        public CompanyMap()
        {
            Table("Company");
            CompositeId().KeyProperty(k => k.Id, "CompanyID").KeyProperty(k => k.EndDate);
            HasMany(x => x.Securities).KeyColumns.Add("CompanyId", "EndDate");
        }       
    }

When I attempt to run this test:

[Test]
public void can_update_a_security()
{
    var repo = IoC.Resolve<ISecurityRepository>();
    int someSecurity = 1;
    using (var work = IoC.Resolve<IUnitOfWorkManager>().Current)
    {
        Security security = repo.Get(someSecurity);
        security.ShouldNotBeNull();
        security.LastUpdateUser = "Dirk Diggler" + DateTime.Now.Ticks;
        repo.Save(security);
        work.Commit();
    }
}

I get the following error deep in the bowels of NHibernate:

Execute System.IndexOutOfRangeException: Invalid index 6 for this SqlParameterCollection with Count=6. at System.Data.SqlClient.SqlParameterCollection.RangeCheck(Int32 index) at System.Data.SqlClient.SqlParameterCollection.GetParameter(Int32 index) at System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index) s:NHibernateNHibernatesrcNHibernateTypeDateTimeType.cs(65,0): at NHibernate.Type.DateTimeType.Set(IDbCommand st, Object value, Int32 index) s:NHibernateNHibernatesrcNHibernateTypeNullableType.cs(180,0): at NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) s:NHibernateNHibernatesrcNHibernateTypeNullableType.cs(139,0): at NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, ISessionImplementor session) s:NHibernateNHibernatesrcNHibernateTypeComponentType.cs(213,0): at NHibernate.Type.ComponentType.NullSafeSet(IDbCommand st, Object value, Int32 begin, ISessionImplementor session) s:NHibernateNHibernatesrcNHibernatePersisterEntityAbstractEntityPersister.cs(2393,0): at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) s:NHibernateNHibernatesrcNHibernatePersisterEntityAbstractEntityPersister.cs(2754,0): 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) s:NHibernateNHibernatesrcNHibernatePersisterEntityAbstractEntityPersister.cs(2666,0): 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) s:NHibernateNHibernatesrcNHibernatePersisterEntityAbstractEntityPersister.cs(2940,0): at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) s:NHibernateNHibernatesrcNHibernateActionEntityUpdateAction.cs(78,0): at NHibernate.Action.EntityUpdateAction.Execute() s:NHibernateNHibernatesrcNHibernateEngineActionQueue.cs(130,0): at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) s:NHibernateNHibernatesrcNHibernateEngineActionQueue.cs(113,0): at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) s:NHibernateNHibernatesrcNHibernateEngineActionQueue.cs(147,0): at NHibernate.Engine.ActionQueue.ExecuteActions() s:NHibernateNHibernatesrcNHibernateEventDefaultAbstractFlushingEventListener.cs(241,0): at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) s:NHibernateNHibernatesrcNHibernateEventDefaultDefaultFlushEventListener.cs(19,0): at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) s:NHibernateNHibernatesrcNHibernateImplSessionImpl.cs(1478,0): at NHibernate.Impl.SessionImpl.Flush() s:NHibernateNHibernatesrcNHibernateTransactionAdoTransaction.cs(187,0): at NHibernate.Transaction.AdoTransaction.Commit() at lambda_method(ExecutionScope , ITransaction )

Now the interesting thing is if I comment out the reference to Company or PrimaryListing in the SecurityMap, I don't get the error. It doesn't seem to matter which I comment out. The error only happens when I have both.

When the update actually goes through NHProf shows me this update:

UPDATE Security
SET    LastUpdateUser = '2010-02-19T08:09:24.00' /* @p0 */,
       CompanyId = 54199 /* @p1 */,
       EndDate = '9999-12-31T00:00:00.00' /* @p2 */
WHERE  SecurityId = 1 /* @p3 */
       AND EndDate = '9999-12-31T00:00:00.00' /* @p4 */

I am not sure why it is updating CompanyId and EndDate, but I suspect it is related.

Any one have ideas? Work arounds would be greatly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Yes its a common problem, you are using the Column "EndDate" twice in your mapping definition (for both Company and PrimaryListing) and that is not allowed. One of them has to go, or have an additional EndDate column (one for each association)

check this too nHibernate 2.0 - mapping a composite-id *and* many-to-one relationship causes "invalid index" error

and http://devlicio.us/blogs/derik_whittaker/archive/2009/03/19/nhibernate-and-invalid-index-n-for-this-sqlparametercollection-with-count-n-error.aspx


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...