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的主要内容,如果未能解决你的问题,请参考以下文章