2009-03-01 3 views
5

ich diese seltsame ArgumentOutOfRangeException immer, wenn ich die PersitenceSpecification Klasse verwenden für die Überprüfung einer Einheit, die eine Verweis auf einen Wert Objekt hat.ArgumentOutOfRangeException: Indexbereich aus war

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

Hier ist der Fehler Ich erhalte:

Testcase 'Then_a_catalog_object_should_be_persistable' nicht ausgeführt: System.ArgumentOutOfRangeException: Index außerhalb des zulässigen Bereichs war. Muss nicht negativ sein und weniger als die Größe der Sammlung. Parametername: Index bei System.ThrowHelper.ThrowArgumentOutOfRangeException (ExceptionArgument Argument ExceptionResource Ressource) bei System.ThrowHelper.ThrowArgumentOutOfRangeException() bei 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 property) d: \ Builds \ FluentNH \ src \ FluentNHibernate \ Testing \ PersistenceSpecification.cs (105,0): bei FluentNHibernate.Testing.PersistenceSpecification`1.VerifyTheMappings () C: \ Source \ Supplychain \ Tests \ Retailer.IntegrationTests \ Zuordnungen \ CatalogItemMappingSpecifications.cs (14,0): bei SupplyChain.Retailer.IntegrationTests.Mappings.When_verifying_the_class_mapping_of_a_catalog_item.Then_a_catalog_object_should_be_persistable ()

Sorry für den langen Post, aber dieses hat mich jetzt für ein paar Stunden beschäftigt. Dies könnte nicht durch FNH verursacht werden, wie ich diese JIRA Ticket von NH fand sich, dass etwas ähnliches erwähnt:

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

Ich hoffe immer noch, dass ich :-) etwas falsch in meinem Code mache. Irgendwelche gedacht?

Vielen Dank im Voraus

Antwort

15

Ich fand die Lösung für dieses Problem, das von meiner eigenen Dummheit in erster Linie resultierte. Alles wurde mir klar, sobald ich die hbm-Dateien aus dem fließenden NH-Mapping generierte.

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

Beachten Sie, dass die Spalte für die Eigenschaft Name und die Spalte für die Hersteller Komponente sind beide auf der gleichen Spalte abgebildet. Deshalb hat dies zu einer ArgumentOutOfRangeException geführt, weil es mehr Argumente gab als es Spaltennamen gab.I gelöst dies durch explizit einen Spaltennamen für die Komponente Mapping spezifiziert:

Komponente (CatalogItem => catalogItem.Manufacturer, m => m.Map (Hersteller => manufacturer.Name, "Hersteller"));

Eine weitere Lektion gelernt.

0

Ihr CatalogItem scheint keine Price Eigenschaft zu haben, die, wenn Sie mit dem Reveal Helfer merkwürdig erscheint.

0

Ja, ich habe das Gerät entfernt, um das Rauschen zu reduzieren. Ich vermute, ich habe vergessen, es auch aus dem Mapping zu entfernen. Nach einigen weiteren Untersuchungen bemerkte ich, dass es etwas damit zu tun hat, dass Manufacturer als eine Komponente abgebildet wird. Wenn ich statt einer separaten Klasse eine einfache alte Zeichenfolge verwendete, funktioniert alles einwandfrei.

0

In meinem speziellen Fall habe ich Eigenschaft sowie ID (mit Attributen) über die gleiche .NET-Eigenschaft hinzugefügt. Dies führte zu demselben Fehler.

2

In meinem Fall habe ich zwei Eigenschaften auf die gleiche Spalte mit Fluent NHibernate zugeordnet.