DB2 session.get()上的NHibernate抛出System.IndexOutOfRangeException

时间:2011-09-26 17:58:30

标签: nhibernate db2

我正在关注NHibernate入门教程:“你的第一个基于NHibernate的应用程序”。我正处于创建Product对象的位置,然后使用Session.get()来证明我可以读取该对象。

它适用于SQL Server Ce,但我在尝试使用DB2时遇到异常。 (SQL Server Ce版本可以工作 - 也就是说。在版本之间有一些小的变化,比如int而不是GUID的GUID。)

我对Hibernate和SQL数据库非常有经验。这是我第一次使用NHibernate和DB2。 (来自Java世界)。我很感激任何建议,尤其是那些在DB2上使用NHibernate的人(显然很少)。

Rob

完整的例外是

  

测试方法Examples.DB2.NHibernateExamples.Can_add_new_product扔了   异常:NHibernate.Exceptions.GenericADOException:无法加载   实体:[Examples.DB2.Domain.Product#1] [SQL:SELECT product0_.Id as   Id1_0_,product0_.Name为Name1_0_,product0_.Category为   Category1_0_,product0_.Discontinued Disconti4_1_0_ FROM Product   product0_ WHERE product0_.Id =?] ---> System.IndexOutOfRangeException:   此CountParameterCollection的索引0无效,Count = 0。

这在以下代码中的Get(...)调用中发生:

    [TestInitialize]
    public void TestInitialize()
    {
        TestFixtureSetup();
        SetupContext();
    }


    [TestMethod]
    public void Can_add_new_product()
    {
        var product = new Product { Id = 1, Name = "Apple", Category = "Fruits"};

        using (ISession session = _sessionFactory.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.Save(product);
                transaction.Commit();
            }
        }

        using (ISession session = _sessionFactory.OpenSession())
        {
            //var query = session.CreateQuery("from Product");
            //var products = query.List<Product>();
            //Assert.AreEqual(1, products.Count);

            var fromDb = session.Get<Product>(product.Id);
            Assert.IsNotNull(fromDb);
            Assert.AreNotSame(product, fromDb);
            Assert.AreEqual(product.Name, fromDb.Name);
            Assert.AreEqual(product.Category, fromDb.Category);
        }
    }

    private void TestFixtureSetup()
    {
        _configuration = new Configuration();
        _configuration.Configure();
        _configuration.AddAssembly(typeof (Domain.Product).Assembly);
        _sessionFactory = _configuration.BuildSessionFactory();
    }

    private void SetupContext()
    {
        new SchemaExport(_configuration).Execute(true, true, false);
    }

异常似乎表明Id参数未传递给DB2查询。如果我在Get()之前取消注释三行,它可以正常工作,因为该行已经被缓存,而Get()实际上没有进入数据库。

以下是Product.cs的定义:

using System;

namespace Examples.DB2.Domain
{
    class Product
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Category { get; set; }
        public virtual bool Discontinued { get; set; }
    }
}

这是Product.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Examples.DB2"
                   namespace="Examples.DB2.Domain">

  <class name="Product">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="Name" />
    <property name="Category" />
    <property name="Discontinued" type="YesNo"/>
  </class>

</hibernate-mapping>

这是hibernate.cfg.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

    <property name="dialect">NHibernate.Dialect.DB2Dialect</property>
    <property name="connection.driver_class">NHibernate.Driver.DB2Driver</property>
    <property name="connection.connection_string">Database=SAMPLE; UID=DEV; PWD=password</property>

    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>

我在Windows 7上使用Visual Studio 2010 Premium。我正在使用DB2 Express-C 9.7.4。

1 个答案:

答案 0 :(得分:1)

确定,

我找到了答案......尚未确定解决方案,但在NHibernate的最终版本中,他们添加了一个名为AdoNet\AbstractBatcher.cs的{​​{1}}来电。此过程调用RemoveUnusedCommandParameters

我现在的解决方案就是注释掉这个调用,让函数什么也不做。

我将与nhusers小组联系,看看是否有更好的长期解决方案。

感谢

DBL