IndexOutOfRangeException Profundamente nas entranhas do NHibernate
Eu tenho os seguintes mapeamentos:
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");
}
}
Quando tento executar este teste:
[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();
}
}
Eu recebo o seguinte erro nas entranhas do NHibernate:
Execute System.IndexOutOfRangeException: índice 6 inválido para este SqlParameterCollection com Count = 6. em System.Data.SqlClient.SqlParameterCollection.RangeCheck (índice Int32) em System.Data.SqlClient.SqlParameterCollection.GetParameter (índice Int32) em System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item (índice Int32) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Type \ DateTimeType.cs (65,0): at NHibernate.Type.DateTimeType.Set (IDbCommand st, Valor do objeto, Valor do objeto, índice Int32) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Type \ NullableType.cs (180,0): em NHibernate.Type.NullableType.NullSafeSet (cmd IDbCommand, valor do objeto, índice Int32) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Type \ NullableType.cs (139,0): em NHibernate.Type.NullableType.NullSafeSet (IDbCommand st, Valor do objeto, índice Int32, sessão ISessionImplementor) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Type \ ComponentType.cs (213,0): em NHibernate.Type.ComponentType. NullSafeSet (IDbCommand st, valor do objeto, início do Int32, sessão ISessionImplementor) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs (2393,0) : at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate (ID do objeto, campos Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, tabela Int32, instrução IDbCommand, ISessionImplementor session, índice Int32) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs (2754,0): em NHibernate.Persister.Entity.AbstractEntityPersister.Update (ID do objeto, campos Object [], Object [], Object [] oldFields, Object rowId, Boolean [ ] includeProperty, Int32 j, Object oldVersion, Obj do objeto, SqlCommandInfo sql, sessão ISessionImplementor) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs (2666,0): em NHibernate.Persister.ters.At .UpdateOrInsert (identificação do objeto, campos Object [], Object [] oldFields, Object rowId, Boolean [] includeProperty, Int32 j, Object oldVersion, Object obj, Object SqlCommandInfo sql, sessão ISessionImplementor) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs (2 940,0): na NHibernate.Persister.Entity.AbstractEntityPersister.Update (ID do objeto, campos Object [], Int32 [] dirtyFields, Boolean hasDirtyCollection, Object [] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor) s : \ NHibernate \ NHibernate \ src \ NHibernate \ Action \ EntityUpdateAction.cs (78,0): em NHibernate.Action.EntityUpdateAction.Execute () s: \ NHibernate \ NHibernate \ src \ NHibernate \ Engine \ ActionQueue.cs (130, 0): em NHibernate.Engine.ActionQueue.Execute (executável IExecutable) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Engine \ ActionQueue.cs (113,0): em NHibernate.Engine.ActionQueue.ExecuteActions (lista IList) s : \ NHibernate \ NHibernate \ src \ NHibernate \ Engine \ ActionQueue.cs (147,0): em NHibernate.Engine.ActionQueue.ExecuteActions () s: \ NHibernate \ NHibernate \ src \ NHibernate \ Evento \ Default \ AbstractFlushingEventListener.cs ( 241,0): em NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions (sessão IEventSource) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Event \ Default \ D efaultFlushEventListener.cs (19,0): em NHibernate.Event.Default.DefaultFlushEventListener.OnFlush (evento FlushEvent) s: \ NHibernate \ NHibernate \ src \ NHibernate \ Impl \ SessionImpl.cs (1478,0): em NHibernate.Impl. SessionImpl.Flush () s: \ NHibernate \ NHibernate \ src \ NHibernate \ Transaction \ AdoTransaction.cs (187,0): em NHibernate.Transaction.AdoTransaction.Commit () em lambda_method (ExecutionScope, ITransaction)
Agora, o interessante é que se eu comentar a referência à Company ou PrimaryListing no SecurityMap, não recebo o erro. Não parece importar o que eu comento. O erro só acontece quando tenho os dois.
Quando a atualização realmente passa pelo NHProf me mostra esta atualização:
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 */
Não sei por que está atualizando CompanyId e EndDate, mas suspeito que esteja relacionado.
Alguém tem ideias? As soluções alternativas seriam muito apreciadas.