2009-03-01 17 views
5

Ricevo questa strana ArgumentOutOfRangeException ogni volta che uso la classe PersitenceSpecification per verificare un'entità che ha un riferimento a un oggetto valore.ArgumentOutOfRangeException: Indice non compreso nell'intervallo

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

Ecco l'errore che sto ricevendo: 'Then_a_catalog_object_should_be_persistable' non eseguito

TestCase : System.ArgumentOutOfRangeException: indice era fuori portata. Deve essere non negativo e inferiore alla dimensione di della raccolta. Nome del parametro: indice a System.ThrowHelper.ThrowArgumentOutOfRangeException (argomento ExceptionArgument, risorsa ExceptionResource) a System.ThrowHelper.ThrowArgumentOutOfRangeException() a 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: \ Costruisce \ FluentNH \ src \ FluentNHibernate \ Testing \ PersistenceSpecification.cs (105,0): a FluentNHibernate.Testing.PersistenceSpecification`1.VerifyTheMappings () C: \ Source \ SupplyChain \ test \ Retailer.IntegrationTests \ Mapping \ CatalogItemMappingSpecifications.cs (14,0): a SupplyChain.Retailer.IntegrationTests.Mappings.When_verifying_the_class_mapping_of_a_catalog_item.Then_a_catalog_object_should_be_persistable ()

Ci scusiamo per il lungo post, ma questo mi ha fatto occupato per un paio d'ore ora. Questo non potrebbe essere causato da FNH come ho trovato questo biglietto JIRA di NH sé che cita qualcosa di simile:

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

sto ancora sperando che sto facendo qualcosa di sbagliato nel mio codice :-). Qual è il pensiero di ?

Grazie in anticipo

risposta

15

Ho trovato la soluzione a questo problema che risultava dalla mia stupidità in primo luogo. Tutto è diventato chiaro per me non appena I ha generato i file hbm dalla fluente mappatura 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> 

Si noti che la colonna per la proprietà Name e la colonna per la componente Fabbricante sono entrambi mappati alla stessa colonna. Ecco perché lo è risultato in ArgumentOutOfRangeException, perché c'erano più argomenti rispetto ai nomi delle colonne.Ho risolto questo specificando esplicitamente un nome di colonna per la mappatura dei componenti:

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

Un'altra lezione appresa.

0

tuo CatalogItem non sembra avere una proprietà Price, che sembra strano quando si utilizza il Reveal aiutante.

0

Sì, l'ho rimosso per ridurre un po 'del rumore. Immagino di aver dimenticato di rimuoverlo anche dalla mappatura. Dopo aver fatto ulteriori indagini, ho notato che ha qualcosa a che fare con il produttore che viene mappato come componente. Quando ho usato una semplice stringa anzichè una classe separata, tutto funziona correttamente.

0

Nel mio caso specifico aggiungevo proprietà e ID (utilizzando attributi) sulla stessa proprietà .NET. Ciò ha comportato lo stesso errore.

2

Nel mio caso, stavo mappando due proprietà sulla stessa colonna con Fluent NHibernate.

Problemi correlati