开发者

NHibernate on DB2 session.get() throws System.IndexOutOfRangeException

I'm following the NHibernate getting started tutorial: "Your first NHibernate based application". I'm at the point where I create a Product object then use Session.get() to prove I can read the object.

It works fine with SQL Server Ce, but I'm getting an exception when I try to use DB2. (The SQL Server Ce version works - that is. There are some minor changes between the versions like int instead of GUID for the Id.)

I'm very experienced with Hibernate and SQL databases. This is my first experience with NHibernate and DB2. (Coming from the Java world). I'd appreciate any suggestions, especially from the (evidently few) people who are using NHibernate on DB2.

Rob

The full exception is

Test method Examples.DB2.NHibernateExamples.Can_add_new_product threw exception: NHibernate.Exceptions.GenericADOException: could not load an entity: [Examples.DB2.Domain.Product#1][SQL: SELECT product0_.Id as Id1_0_, product0_.Name as Name1_0_, product0_.Category as Category1_0_, product0_.Discontinued as Disconti4_1_0_ FROM Product product0_ WHERE product0_.Id=?] ---> System.IndexOutOfRangeException: Invalid index 0 for this DB2ParameterCollection with Count=0.

This is happening in the Get(...) call in the following code:

    [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);
    }

The exception seems to indicate that the Id paramter isn't being passed to the DB2 query. If I uncomment the three lines before the Get(), it works fine since the row is already cached and the Get() doesn't actually go to the database.

Here is the definition of 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; }
    }
}

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

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

I'm working in Visual Studio 2010 Premium on Windows 7. I'm using DB2 Express-C 9.7.4.


Ok,

I found the answer ... not exactly sure of the solution yet, but in the final release of NHibernate they added a call to AdoNet\AbstractBatcher.cs called RemoveUnusedCommandParameters. This procedure calls Driver.RemoveUnusedCommandParameters.

My solution for now is just to comment out this call and let the function do nothing.

I will bring this up with the nhusers group and see if there is a better long term solution.

thanks

dbl

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜