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 filter out parameter 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 filters out this type, the parameter is
stripped out, and you now have one less parameter than you should, so when
the query is bound, you get an index out of 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 : Index was out of range.
Hi,
I'm getting this weird ArgumentOutOfRangeException whenever 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 : Index was out of
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(Int32 index)
at System.Data.SQLite.SQLiteParameterCollection.GetParameter
(Int32
index)
at
System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item
(Int32 index)
at NHibernate.Type.GuidType.Set(IDbCommand cmd, 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.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
FluentNHibernate.Testing.PersistenceSpecification`1.TransactionalSave
(Object propertyValue)
d:\Builds\FluentNH\src\FluentNHibernate\Testing
\PersistenceSpecification.cs(105,0): at
FluentNHibernate.Testing.PersistenceSpecification`1.VerifyTheMappings
()
C:\Source\SupplyChain\Tests\Retailer.IntegrationTests\Mappings
\CatalogItemMappingSpecifications.cs(14,0): at
SupplyChain.Retailer.IntegrationTests.Mappings.When_verifying_the_class_mapp
ing_of_a_catalog_item.Then_a_catalog_object_should_be_persistable
()
Sorry for the long post, but this one got me busy for a couple of
hours now. This might not be caused by FNH as I found this JIRA ticket
of NH itself that mentions something similar:
http://forum.hibernate.org/viewtopic.php?p=2395409
I'm still hoping that I'm doing something wrong in my code :-). Any
thought?
Thanks in advance
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---