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

Posted

技术标签:

【中文标题】DB2 session.get() 上的 NHibernate 抛出 System.IndexOutOfRangeException【英文标题】:NHibernate on DB2 session.get() throws System.IndexOutOfRangeException 【发布时间】:2011-09-26 17:58:29 【问题描述】:

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

它适用于 SQL Server Ce,但是当我尝试使用 DB2 时出现异常。 (SQL Server Ce 版本有效 - 也就是说。版本之间有一些细微的变化,例如 int 而不是 Id 的 GUID。)

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

罗伯

完整的例外是

测试方法Examples.DB2.NHibernateExamples.Can_add_new_product throw 异常: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 as Disconti4_1_0_ FROM Product product0_ WHERE product0_.Id=?] ---> System.IndexOutOfRangeException: 此 DB2ParameterCollection 的索引 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】:

好的,

我找到了答案……还不确定解决方案,但在NHibernate 的最终版本中,他们添加了对AdoNet\AbstractBatcher.cs 的调用,称为RemoveUnusedCommandParameters。此过程调用Driver.RemoveUnusedCommandParameters

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

我会向 nhusers 小组提出这个问题,看看是否有更好的长期解决方案。

谢谢

dbl

【讨论】:

感谢您的回复。我没有立即看到它,因为它没有发送到我的电子邮件中。必须处理我的个人资料。

以上是关于DB2 session.get() 上的 NHibernate 抛出 System.IndexOutOfRangeException的主要内容,如果未能解决你的问题,请参考以下文章

IBM Cloud 上的 Db2 的 SQL 格式是啥?

获取 DB2 上的索引列

text #docker上的#db2

cobol 上的外部存储过程 db2

用于模式的 zOS 目录表上的 DB2?

尝试使用 MicroStrategy 连接时 DB2 上的 SQLCODE -1334