I found the solution to this problem which resulted from my own
stupidity in the first place. It all became clear to me as soon as I
generated the hbm files from the fluent NH mapping.

<class name="CatalogItem" table="`CatalogItem`" xmlns="urn:nhibernate-
mapping-2.2" optimistic-lock="version">
    ...

    <property name="Name" length="100" type="String">
      <column name="Name" />
    </property>

    ...

    <component name="Manufacturer" insert="false" update="true">
      <property name="Name" length="100" type="String">
        <column name="Name" />
      </property>
    </component>
  </class>

Notice that the column for the Name property and the column for the
Manufacturer component are both mapped to the same column. That's why
this resulted into an ArgumentOutOfRangeException, because there were
more arguments than there were column names. I solved this by
explicitely specifying a column name for the component mapping:

Component(catalogItem => catalogItem.Manufacturer,
                      m => m.Map(manufacturer => manufacturer.Name,
"Manufacturer"));

Another lesson learned.


On Mar 3, 11:46 pm, Jan Van Ryswyck <[email protected]> wrote:
> I've tried this with SQL CE and it practically gives me the same
> error:
>
> System.IndexOutOfRangeException : An SqlCeParameter with
> ParameterIndex '5' is not contained by this SqlCeParameterCollection.
>
> The error occurs when NH tries to insert a CatalogItem in the
> database:
>
>     public class CatalogItem : DomainEntity
>     {
>         private String Description { get; set; }
>         internal virtual Manufacturer Manufacturer { get; private
> set; }
>         internal virtual String Name { get; private set; }
>         private Double Price { get; set; }
>         private Product Product { get; set; }
>
>        ...
>     }
>
> public class CatalogCategory : DomainEntity
>     {
>         private ISet<CatalogItem> Items { get; set; }
>         internal virtual String Name { get; private set; }
>
>         protected CatalogCategory()
>         {
>             Items = new HashedSet<CatalogItem>();
>         }
>
>         ...
>     }
>
> The following gets generated from the schema export:
>
> create table "CatalogCategory" (Id UNIQUEIDENTIFIER not null, Name
> TEXT, Catalog_id UNIQUEIDENTIFIER, primary key (Id))
>
> create table "CatalogItem" (Id UNIQUEIDENTIFIER not null, Name TEXT,
> Price NUMERIC, Description TEXT, Number INTEGER,
> CatalogCategory_id UNIQUEIDENTIFIER, primary key (Id))
>
> When NH tries to insert a record into the "CatalogItem" table, it only
> has 5 parameters instead of 6. The one that's missing is
> CatalogCategory_id. The exception occurs in the GuidType class of NH
> in the following function:
>
>                 public override void Set(IDbCommand cmd, object value, int 
> index)
>                 {
>                         ((IDataParameter)cmd.Parameters[index]).Value = value;
>                 }
>
> Because the Parameters collection only has 5 parameters, 
> anArgumentOutOfRangeExceptionis thrown when the specified index is 5.
> For some reason, the parameter for the CatalogCategory_id is missing.
> Any thoughts?
>
> On 1 mrt, 23:19, Jan Van Ryswyck <[email protected]> wrote:
>
> > Thx for sharing this. I'll investigate this further tomorrow evening
> > and try to debug to the point in the code that you mentioned. It will
> > probably be something similar. There is a entry in the NH Jira for
> > this but for Oracle (NH-1477). Maybe you  could add your case as well?
>
> > On 1 mrt, 22:00, "Robert Byrne" <[email protected]> wrote:
>
> > > I just debugged a problem very similar to this one, again using SQLite.
>
> > > The problem (a strange and elusive one) in my case was that I was using a
> > > the same column for a discriminator and a many-to-one.
>
> > > I tracked the problem down to SqlInsertBuilder.GetParametersTypeArray(), 
> > > it
> > > uses a class called SafetyEnumerable<T> to filteroutparameter types that
> > > are not assignable to T (which in this case is SqlType). The problem is 
> > > that
> > > for some reason when you use the same column for a discriminator and a
> > > many-to-one, NHibernate doesn't pick up the type correctly, it actually 
> > > uses
> > > the discriminator-value instead of the type, for example, the elements 
> > > being
> > > enumerated look something like:
>
> > > {[
> > > "Name"=String,
> > > "Description"=String,
> > > "DataFieldType"='32',
> > > "Id"=Int32
> > > ]}
>
> > > Notice that the value for DataFieldType is the literal string '32' (which 
> > > is
> > > the discriminator-value for this subclass), when it should be Int32 (like
> > > the Id column below it). Explicitly specifying the type on the
> > > <discriminator> element in the mapping doesn't help.
>
> > > Because SafetyEnumerable quietly filtersoutthis type, the parameter is
> > > strippedout, and you now have one less parameter than you should, so when
> > > the query is bound, you get anindexoutof bounds exception.
>
> > > I'm not sure if this is the exact same problem in your case, but if you 
> > > set
> > > a breakpoint in the above method you can have a look at columns.Values and
> > > try and look for something similar.
>
> > > If there isn't an open bug for this (there should be an exception if the
> > > mapping is invalid, or SafetyEnumerable should throw in this case etc) 
> > > then
> > > I'll post one with steps to reproduce. Let me know.
>
> > > By the way, the fix in my case was to remove the many-to-one mapping.
> > > Thankfully it was an iffy design choice so I could live without it.
>
> > > Hopefully this will save someone else a Sunday afternoon :)
>
> > > -----Original Message-----
> > > From: [email protected] [mailto:[email protected]] On Behalf
>
> > > Of Jan Van Ryswyck
> > > Sent: 28 February 2009 20:06
> > > To: nhusers
> > > Subject: [nhusers]ArgumentOutOfRangeException:Indexwasoutofrange.
>
> > > Hi,
>
> > > I'm getting this weirdArgumentOutOfRangeExceptionwhenever I use the
> > > PersitenceSpecification class for verifying an entity that has a
> > > reference to a value object.
>
> > >     public class CatalogItem : DomainEntity
> > >     {
> > >         internal virtual Manufacturer Manufacturer { get; private
> > > set; }
> > >         internal virtual String Name { get; private set; }
>
> > >         protected CatalogItem()
> > >         {}
>
> > >         public CatalogItem(String name, String manufacturer)
> > >         {
> > >             Name = name;
> > >             Manufacturer = new Manufacturer(manufacturer);
> > >         }
> > >     }
>
> > >     public class CatalogItemMapping : ClassMap<CatalogItem>
> > >     {
> > >         public CatalogItemMapping()
> > >         {
> > >             Id(catalogItem => catalogItem.Id);
>
> > >             Component<Manufacturer>(category => category.Manufacturer,
> > >                                     m => m.Map(manufacturer =>
> > > manufacturer.Name));
>
> > >             Map(catalogItem => catalogItem.Name);
> > >             Map(Reveal.Property<CatalogItem>("Price"));
> > >         }
> > >     }
>
> > >     [TestFixture]
> > >     public class When_verifying_the_class_mapping_of_a_catalog_item
> > >         : NHibernateSpecification
> > >     {
> > >         [Test]
> > >         public void Then_a_catalog_object_should_be_persistable()
> > >         {
> > >             new PersistenceSpecification<CatalogItem>(Session)
> > >                 .VerifyTheMappings();
> > >         }
> > >     }
>
> > >     [TestFixture]
> > >     public class NHibernateSpecification
> > >         : Specification
> > >     {
> > >         protected ISession Session { get; private set; }
>
> > >         protected override void Establish_context()
> > >         {
> > >             var configuration = new SQLiteConfiguration()
> > >                 .InMemory()
> > >                 .ShowSql()
> > >                 .ToProperties();
>
> > >             var sessionSource = new SessionSource(configuration, new
> > > RetailerPersistenceModel());
> > >             Session = sessionSource.CreateSession();
>
> > >             sessionSource.BuildSchema(Session);
> > >             ProvideInitialData(Session);
>
> > >             Session.Flush();
> > >             Session.Clear();
> > >         }
>
> > >         protected override void Dispose_context()
> > >         {
> > >             Session.Dispose();
> > >             Session = null;
> > >         }
>
> > >         protected virtual void ProvideInitialData(ISession session)
> > >         {}
> > >     }
>
> > > Here's the error I'm getting:
>
> > > TestCase 'Then_a_catalog_object_should_be_persistable'
> > > not executed: System.ArgumentOutOfRangeException:Indexwasoutof
> > >range. Must be non-negative and less than the size of the collection.
> > > Parameter name:index
> > >         at System.ThrowHelper.ThrowArgumentOutOfRangeException
> > > (ExceptionArgument argument, ExceptionResource resource)
> > >         at System.ThrowHelper.ThrowArgumentOutOfRangeException()
> > >         at System.Collections.Generic.List`1.get_Item(Int32index)
> > >         at System.Data.SQLite.SQLiteParameterCollection.GetParameter
> > > (Int32
> > >index)
> > >         at
> > > System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item
> > > (Int32index)
> > >         at NHibernate.Type.GuidType.Set(IDbCommand cmd, Object value,
> > > Int32
> > >index)
> > >         at NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd,
> > > Object
> > > value, Int32index)
> > >         at NHibernate.Type.NullableType.NullSafeSet(IDbCommand st,
> > > Object
> > > value, Int32index, ISessionImplementor session)
> > >         at
> > > NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate
> > > (Object id, Object[] fields, Object rowId, Boolean[] includeProperty,
> > > Boolean[][] includeColumns, Int32 table, IDbCommand statement,
> > > ISessionImplementor session, Int32index)
> > >         at NHibernate.Persister.Entity.AbstractEntityPersister.Insert
> > > (Object
> > > id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql,
> > > Object obj, ISessionImplementor session)
> > >         at NHibernate.Persister.Entity.AbstractEntityPersister.Insert
> > > (Object
> > > id, Object[] fields, Object obj, ISessionImplementor session)
> > >         at NHibernate.Action.EntityInsertAction.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()
> > >         d:\Builds\FluentNH\src\FluentNHibernate\Testing
> > > \PersistenceSpecification.cs(127,0): at
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to