NHibernate в DB2 session.get () создает исключение System.IndexOutOfRangeException - PullRequest
2 голосов
/ 26 сентября 2011

Я следую руководству по началу работы с NHibernate: «Ваше первое приложение на основе NHibernate». Я нахожусь в точке, где я создаю объект Product, а затем использую Session.get (), чтобы доказать, что я могу прочитать объект.

Он отлично работает с SQL Server Ce, но я получаю исключение при попытке использовать DB2. (Версия SQL Server Ce работает - то есть. Есть некоторые незначительные изменения между версиями, такими как int вместо GUID для идентификатора.)

У меня большой опыт работы с базами данных Hibernate и SQL. Это мой первый опыт работы с NHibernate и DB2. (Исходя из мира Java). Буду признателен за любые предложения, особенно от (очевидно, немногих) людей, которые используют NHibernate в DB2.

Роб

Полное исключение:

Тестовый метод examples.DB2.NHibernateExamples.Can_add_new_product threw исключение: NHibernate.Exceptions.GenericADOException: не удалось загрузить объект: [examples.DB2.Domain.Product # 1] [SQL: SELECT product0_.Id as Id1_0_, product0_.Name as Name1_0_, product0_.Category as Category1_0_, product0_. Прекращено как Disconti4_1_0_ ИЗ ПРОДУКТА product0_ WHERE product0_.Id =?] ---> System.IndexOutOfRangeException: Неверный индекс 0 для этой коллекции DB2ParameterCollection с числом = 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>

Я работаю в Visual Studio 2010 Premium на Windows 7. Я использую DB2 Express-C 9.7.4.

1 Ответ

1 голос
/ 08 ноября 2011

Хорошо,

Я нашел ответ ... пока не совсем уверен в решении, но в финальной версии NHibernate они добавили вызов AdoNet\AbstractBatcher.cs с именем RemoveUnusedCommandParameters. Эта процедура вызывает Driver.RemoveUnusedCommandParameters.

Мое решение на данный момент - просто закомментировать этот вызов и позволить функции ничего не делать.

Я расскажу об этом группе nhusers и посмотрю, есть ли лучшее долгосрочное решение.

спасибо

дублированный

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...