5

每当我使用 PersitenceSpecification 类来验证具有对值对象的引用的实体时,我都会收到这个奇怪的 ArgumentOutOfRangeException。

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

这是我得到的错误:

未执行测试用例“Then_a_catalog_object_should_be_persistable”:System.ArgumentOutOfRangeException:索引超出范围。必须是非负数且小于集合的大小。参数名称:System.ThrowHelper.ThrowArgumentOutOfRangeException 处的索引(ExceptionArgument 参数,ExceptionResource 资源)处 System.ThrowHelper.ThrowArgumentOutOfRangeException() 处 System.Collections.Generic.List1.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.PersistenceSpecification1.TransactionalSave (Object propertyValue) d:\Builds\FluentNH\src\FluentNHibernate\Testing\PersistenceSpecification.cs(105,0): 在 FluentNHibernate.Testing.PersistenceSpecification`1.VerifyTheMappings() C:\Source\SupplyChain\Tests\ Retailer.IntegrationTests\Mappings\CatalogItemMappingSpecifications.cs(14,0):在 SupplyChain.Retailer.IntegrationTests.Mappings.When_verifying_the_class_mapping_of_a_catalog_item.Then_a_catalog_object_should_be_persistable ()

很抱歉这篇长文,但这一篇让我忙了几个小时。这可能不是由 FNH 引起的,因为我发现这张 NH 本身的 JIRA 票中提到了类似的内容:

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

我仍然希望我在我的代码中做错了什么:-)。任何想法?

提前致谢

4

7 回答 7

15

我找到了解决这个问题的方法,这首先是我自己的愚蠢造成的。当我从流畅的 NH 映射生成 hbm 文件时,这一切都变得清晰起来。

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

请注意,Name 属性的列和 Manufacturer 组件的列都映射到同一列。这就是导致 ArgumentOutOfRangeException 的原因,因为参数比列名多。我通过明确指定组件映射的列名解决了这个问题:

组件(catalogItem => catalogItem.Manufacturer,m => m.Map(manufacturer => Manufacturer.Name,“制造商”));

另一个教训。

于 2009-03-06T21:28:24.493 回答
2

就我而言,我使用 . 将两个属性映射到同一列Fluent NHibernate

于 2012-09-29T01:28:42.300 回答
0

CatalogItem似乎没有Price属性,当您使用Reveal帮助器时这似乎很奇怪。

于 2009-03-01T20:46:30.827 回答
0

是的,我删除了那个以减少一些噪音。我想我也忘了从映射中删除它。在进行了更多调查后,我注意到它与将制造商映射为组件有关。当我使用普通的旧字符串而不是单独的类时,一切正常。

于 2009-03-02T06:35:52.907 回答
0

在我的特殊情况下,我在同一个 .NET 属性上添加属性和 ID(使用属性)。这导致了同样的错误。

于 2010-08-22T10:00:41.697 回答
0

老问题,但如果有人遇到和我一样的问题,知道这个 Fluent Nhibernate 问题(ColumnPrefix 仅应用于 ComponentMap 内的第一个组件映射)可能会给出相同的异常,因为列前缀并不总是适用.

于 2014-05-23T12:21:01.867 回答
0

这个问题的其他答案是正确的。但是还有另一种情况,NHibernate 输出具有不同堆栈跟踪的相同消息。堆栈跟踪可以在这个问题中找到。

由于这是我在网上搜索确切错误消息时弹出的首要问题之一,我认为其他人知道我如何修复它会有所帮助。在 NHibernate 的 GitHub 存储库中,有一个针对此错误的记录问题。这是链接 - https://github.com/nhibernate/nhibernate-core/issues/1319

在撰写此答案时,该错误已在最新的 NHibernate 中得到修复。对于旧版本,例如 3.1.0(我遇到错误时正在使用的版本),在文件中将format_sql属性设置为 false可以解决问题。nhibernate.config有关错误和解决方法的更多详细信息可以在 GitHub 问题和NHibernate 文档中找到。

于 2021-09-18T07:01:54.497 回答