2011-09-26 2 views
2

Je suis le tutoriel de mise en route de NHibernate: "Votre première application basée sur NHibernate". Je suis au point où je crée un objet Product puis j'utilise Session.get() pour prouver que je peux lire l'objet.NHibernate sur DB2 session.get() throws System.IndexOutOfRangeException

Cela fonctionne très bien avec SQL Server Ce, mais je reçois une exception lorsque j'essaie d'utiliser DB2. (La version SQL Server Ce fonctionne, c'est-à-dire qu'il y a quelques changements mineurs entre les versions comme int au lieu de GUID pour l'Id.)

Je suis très expérimenté avec les bases de données Hibernate et SQL. C'est ma première expérience avec NHibernate et DB2. (Venant du monde Java). J'apprécierais toutes les suggestions, en particulier de la part des personnes (évidemment peu nombreuses) qui utilisent NHibernate sur DB2.

Rob

L'exception complète est

Méthode d'essai Examples.DB2.NHibernateExamples.Can_add_new_product a lancé exception: NHibernate.Exceptions.GenericADOException: ne pouvait pas charger une entité: [Examples.DB2. Domain.Product # 1] [SQL: SELECT product0_.Id en tant que Id1_0_, product0_.Name en tant que Name1_0_, product0_.Catégorie en tant que Category1_0_, product0_.Discontinué en tant que Disconti4_1_0_ FROM Produit product0_ WHERE product0_.Id =?] ---> System.IndexOutOf RangeException: Index 0 invalide pour ce DB2ParameterCollection avec Count = 0.

Cela se passe dans le Get (...) appel dans le code suivant:

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

L'exception semble indiquer que le paramter Id n'est pas transmise à la requête DB2. Si je décommente les trois lignes avant le Get(), cela fonctionne bien car la ligne est déjà mise en cache et le Get() ne va pas réellement à la base de données.

Voici la définition de 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; } 
    } 
} 

Voici 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> 

Voici 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> 

Je travaille dans Visual Studio 2010 Premium sous Windows 7. J'utilise DB2 Express-C 9.7.4.

Répondre

1

Ok,

J'ai trouvé la réponse ... pas exactement de la solution encore, mais dans la version finale de NHibernate ils ont ajouté un appel à AdoNet\AbstractBatcher.cs appelé RemoveUnusedCommandParameters. Cette procédure appelle Driver.RemoveUnusedCommandParameters.

Ma solution pour l'instant est juste de commenter cet appel et laisser la fonction ne rien faire.

Je vais en parler avec le groupe nhusers et voir s'il y a une meilleure solution à long terme.

grâce

dbl

+0

Merci pour la réponse. Je ne l'ai pas vu tout de suite, car il n'a pas été envoyé à mon email. Je dois travailler sur mon profil. –

Questions connexes