2009-03-01 13 views
5

Obtengo esta extraña excepción ArgumentOutOfRangeException cada vez que uso la clase PersitenceSpecification para verificar una entidad que tiene una referencia a un objeto de valor.ArgumentOutOfRangeException: El índice estaba fuera del rango

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) 
     {} 
    } 

Aquí está el error que estoy consiguiendo: 'Then_a_catalog_object_should_be_persistable' no ejecutado

TestCase : System.ArgumentOutOfRangeException: índice estaba fuera del rango. Debe ser no negativo y menor que el tamaño de la colección. Nombre de parámetro: índice en System.ThrowHelper.ThrowArgumentOutOfRangeException (argumento ExceptionArgument, recurso ExceptionResource) en System.ThrowHelper.ThrowArgumentOutOfRangeException() en 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: \ Construye \ FluentNH \ src \ FluentNHibernate \ Prueba \ PersistenceSpecification.cs (105,0): en FluentNHibernate.Testing.PersistenceSpecification`1.VerifyTheMappings () C: \ Source \ SupplyChain \ Ensayos \ Retailer.IntegrationTests \ Asignaciones \ CatalogItemMappingSpecifications.cs (14,0): en SupplyChain.Retailer.IntegrationTests.Mappings.When_verifying_the_class_mapping_of_a_catalog_item.Then_a_catalog_object_should_be_persistable ()

Lo siento por el largo post, pero éste me tiene ocupado durante un par de horas ahora. Esto no podría ser causada por la HNF como descubrí este billete JIRA de por sí NH que menciona algo similar:

http://forum.hibernate.org/viewtopic.php?p=2395409

Todavía estoy esperando que estoy haciendo algo mal en mi código :-). ¿Alguna idea de ?

Gracias de antemano

Respuesta

15

Encontré la solución a este problema que resultó de mi propia estupidez en primer lugar. Todo quedó claro para mí tan pronto como yo generé los archivos hbm desde la fluida asignación de NH.

<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> 

en cuenta que la columna para la propiedad Name y la columna para el componente Fabricante se asigna a ambos la misma columna. Es por eso que esto resultó en una excepción ArgumentOutOfRangeException, porque había más argumentos que nombres de columna.He resuelto este por explícitamente especificando un nombre de columna para el mapeo componente:

componente (CatalogItem => catalogItem.Manufacturer, m => m.Map (fabricante => manufacturer.Name, "Fabricante"));

Otra lección aprendida.

0

Su CatalogItem no parecen tener una propiedad Price, que parece extraño cuando se está utilizando el ayudante Reveal.

0

Sí, eliminé esa para reducir parte del ruido. Supongo que olvidé eliminarlo del mapeo también. Después de investigar un poco más, me di cuenta de que tiene algo que ver con que el fabricante se mapee como componente. Cuando utilicé una cadena simple antigua en lugar de una clase separada, todo funciona bien.

0

En mi caso particular, estaba agregando propiedad y también ID (usando atributos) sobre la misma propiedad .NET. Esto resultó en el mismo error.

2

En mi caso, estaba mapeando dos propiedades en la misma columna con Fluent NHibernate.

Cuestiones relacionadas