Index out of range exception in caused by wrong calculation in AbstractEntityPersister.Dehydrate method

306 views
Skip to first unread message

Ramon Smits

unread,
Sep 30, 2008, 6:29:35 AM9/30/08
to nhusers
My code fails on an update.

+ $exception {"Invalid index 14 for this SqlParameterCollection with
Count=14."} System.Exception {System.IndexOutOfRangeException}

Which seems logical as there are 14 items. The index supplied to the
method is wrong and calculated by the following code in the
AbstractEntityPersister.Dehydrate method:


for (int i = 0; i < entityMetamodel.PropertySpan; i++)
{
if (includeProperty[i] && IsPropertyOfTable(i, table))
{
PropertyTypes[i].NullSafeSet(statement, fields[i], index,
includeColumns[i], session);
index += ArrayHelper.CountTrue(includeColumns[i]); //TODO: this
is kinda slow...
}
}

This results in the index be set to 14 and then calls:

IdentifierType.NullSafeSet(statement, id, index, session);

Which results in an Invalid index exception


I really don't know what that for loop is doing but the sql statement
contains a parameter collection which contains values that do not map
correctly. The following query is generated:


UPDATE
xxx.dbo.yyy
SET
Name = @p0, --1
Status_id = @p1, -- 20080925_3
StartDateTime = @p2, -- 5
Type_Id = @p3, -- {25-9-2008 12:15:00}
Skin = @p4, -- null
Start = @p5, --null
End = @p6, --null
StatsEnabled = @p7, --null
Title = @p8,
Creator = @p9,
CustomerUrl = @p10,
Process_Status = @p11,
Customer_Id = @p12
WHERE
Id = @p13"


The value of Status_Id should be assigned to Name... The value of
StartDateTime to Status_Id, etc. and where I *think* but do not know
for sure at the moment is that the value for @P1 (Name) should be the
value for @p12. But I will try to test that with other data.

I really do not know what is going wrong here. Anybody having ideas?

Fabio Maulo

unread,
Sep 30, 2008, 7:10:38 AM9/30/08
to nhu...@googlegroups.com
mappings please.

2008/9/30 Ramon Smits <ramon...@gmail.com>



--
Fabio Maulo

Ramon Smits

unread,
Sep 30, 2008, 7:44:03 AM9/30/08
to nhusers
> mappings please.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Dal"
namespace="Dal">

<class name="yyy">
<id name="Id">
<generator class="native"/>
</id>
<property name="Customer_Id" />
<property name="Name" />
<property name="Status_id" />
<property name="StartDateTime" />
<property name="Type_Id" />
<property name="Skin" />
<property name="Start" />
<property name="End" />
<property name="StatsEnabled" />
<property name="Title" />
<property name="Creator" />
<property name="CustomerUrl" />
<property name="Process_Status" />

<bag name="AAAs" table="yyy_AAA">
<key column="yyy_Id"/>
<many-to-many class="AAA" column="AAA_Id"/>
</bag>

<bag name="BBBs" table="yyy_BBB">
<key column="yyy_Id"/>
<many-to-many class="BBB" column="BBB_Id"/>
</bag>

<bag name="CCCs" table="yyy_CCC">
<key column="yyy_Id"/>
<many-to-many class="CCC" column="CCC_Id"/>
</bag>

<bag name="DDD">
<key column="yyy_Id"/>
<one-to-many class="DDD"/>
</bag>

<bag name="EEE">
<key column="yyy_Id" />
<one-to-many class="EEE"/>
</bag>

<bag name="FFF">
<key column="yyy_Id" />
<one-to-many class="FFF"/>
</bag>

<bag name="GGG">
<key column="yyy_Id" />
<one-to-many class="GGG"/>
</bag>

<bag name="HHH">
<key column="yyy_Id" />
<one-to-many class="HHH"/>
</bag>

<bag name="III">
<key column="yyy_Id"/>
<one-to-many class="III"/>
</bag>

<bag name="JJJ">
<key column="yyy_Id"/>
<one-to-many class="JJJ"/>
</bag>

<bag name="KKK">
<key column="yyy_Id"/>
<one-to-many class="KKK"/>
</bag>

<bag name="LLL">
<key column="yyy_Id"/>
<one-to-many class="LLL"/>
</bag>

<bag name="MMM">
<key column="yyy_Id"/>
<one-to-many class="MMM"/>
</bag>

<bag name="NNN">
<key column="yyy_Id"/>
<one-to-many class="NNN"/>
</bag>

<bag name="OOO">
<key column="yyy_Id"/>
<one-to-many class="OOO"/>
</bag>

<many-to-one name="Customer" class="Customer"
column="Customer_Id" />

</class>
</hibernate-mapping>


I have anonymized the entities a bit but only the names are replaced.
The structure is the same.

Fabio Maulo

unread,
Sep 30, 2008, 7:53:12 AM9/30/08
to nhu...@googlegroups.com
You have two properties mapped to the same column.
Use insert=false and update=false in one of the two.
Bye.
Fabio Maulo.

P.S. Your mapping is a classic example of how DON'T map a class. Try to set lazy=false and see what happen, and think when you need all thats collections together... you are delegating some work of your BusinessLayer to the DAL (NH).

2008/9/30 Ramon Smits <ramon...@gmail.com>



--
Fabio Maulo

Ramon Smits

unread,
Sep 30, 2008, 8:24:45 AM9/30/08
to nhusers

> You have two properties mapped to the same column.Use insert=false and
> update=false in one of the two.

You refer to the Customer and Customer_Id columns I guess.

Will try that!

> P.S. Your mapping is a classic example of how DON'T map a class. Try to set
> lazy=false and see what happen, and think when you need all thats
> collections together... you are delegating some work of your BusinessLayer
> to the DAL (NH).

I know the performance impact of lazy loading but when I don't need
all data I do lazy loading as I won't fetch data through all those
properties and I use eager loading when I need all the data which is
often required because we have fat xml messages between systems.

Why would this be a bad design as it performs quite well :-)

Grtz,
Ramon

Ramon Smits

unread,
Sep 30, 2008, 9:28:09 AM9/30/08
to nhusers

> You have two properties mapped to the same column.Use insert=false and
> update=false in one of the two.

This fixes the problem. Thanks!

--
Ramon
Reply all
Reply to author
Forward
0 new messages