NHibernate 3 (Parte 1) Un mapeo simple

Published on Author lopez1 Comment

Siguiente post

Hace año y medio escribí un ejemplo en NHibernate 2.0:

First NHibernate 2.x Example

Este año que recién comienza, quiero explorar el nuevo release NHibernate 3.0 con ejemplos. Pueden bajar la versión actual de este ORM para .NET desde:

http://sourceforge.net/projects/nhibernate/files/

Uso NHibernate-3.0.0.GA-bin.zip para la solución:

Mantengo este ejempo en mi proyecto AjCodeKatas, en el directorio trunk/NHibernate/SimpleMapping. El código no incluye las librerías de NHibernate, así que tienen que agregar las referencias a los proyectos. Yo agregué al proyecto SimpleMapping.Console todas las .dll de los directorios de NHibernate NHibernate Required_Bins y Required_For_LazyLoading\Castle.

Si son perezosos, como yo ;-), pueden directamente bajarse el ejemplo completo con las librerías incluidas desde mi Skydrive: NHibernate3SimpleMapping.zip.

Noten que creé una solución con un Solution folder Schemas, en el que agregué los archivos de esquemas .xsd que encontré en el directorio Required_Bins dentro de la distribución binaria de NHibernate. Esto permite que puedan usar Intellisense cuando escriban algunos archivos que NHibernate necesita.

El proyecto SimpleMapping.Domain NO referencia a NHibernate (una prueba de la independencia de nuestro dominio de la persistencia) y contiene una sola clase:

    public class Customer
    {
        public virtual Guid Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Address { get; set; }
        public virtual string Notes { get; set; }
    }

Escribí un app.config en la aplicación de consola:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section
    name="hibernate-configuration"
    type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"
/>
  </configSections>
  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <property name="connection.connection_string">Data Source=.\SQLEXPRESS;Initial Catalog=NHibernate3SimpleMapping;Integrated Security=True</property>
      <property name="proxyfactory.factory_class">
        NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
      </property>
      <mapping assembly="SimpleMapping.Console" />
    </session-factory>
  </hibernate-configuration>
</configuration>

Tenemos que ir estudiando los parámetros que necesita NHibernate. Pero a simple vista: aparece el string de conexión, y el dialecto. Vamos a tener que estudiar qué es esos del dialecto: un adelanto rápido, es la clase de NHibernate que sabe cómo generar comandos SQL para la base de datos que estemos usando. NHibernate puede acceder a otros tipos de bases de datos, no sólo a SQL Server, y el dialecto es la forma que tiene de poder generar comandos SQL especiales para cada base de datos (por ejemplo, el manejo de recuperación autonuméricos).

Escribí un archivo Customer.hbm.xml. Atención: Lo marqué como Embedded Resources en su ventana de propiedades. No se olviden de este paso: en este ejemplo, le estamos diciendo en el parámetro mapping de la configuración de más arriba, que todos los mapeos están incluidos en el assembly SimpleMapping.Console. Vean que las clases pueden estar definidas en un proyecto, y los mapeos en otro. Este es el contenido del Customer.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="SimpleMapping.Domain"
namespace="SimpleMapping.Domain">
  <class name="Customer" table="Customers">
    <id name="Id">
      <generator class="guid.comb" />
    </id>
    <property name="Name" not-null="true" />
    <property name="Address" />
    <property name="Notes" />
  </class>
</hibernate-mapping>

Para crear la base de datos, pueden ejecutar Sql\ExecuteAll.cmd (ver Readme.txt para más detalles).

El programa de consola solamente crea un cliente, lo graba en la base, y recupera todos los clientes existentes:

    ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
    using (ISession session = sessionFactory.OpenSession())
    {
        using (ITransaction tx = session.BeginTransaction())
        {
            Customer customer1 = new Customer();
            customer1.Name = "Customer 1";
            customer1.Address = "Address 1";
            customer1.Notes = "Notes 1";
            session.Save(customer1);
            IQuery query = session.CreateQuery("from Customer");
    
            foreach (Customer c in query.List<Customer>())
                System.Console.WriteLine(string.Format("Customer {0}", c.Name));
            tx.Commit();
            session.Close();
        }
    }

(Disculpen, no estoy muy creativo para los los valores de las propiedades 馃槈

Hay varios detalles para discutir: ¿Qué es eso del Castle bytecode? ¿Para qué sirve cada propiedad que pusimos en la configuración? ¿Qué es una session? ¿Y una transacción? ¿Qué es un Id? ¿Qué es un guid.comb? ¿Qué alternativas tenemos a haber puesto ese valor? ¿Cómo mapear una propiedad de otro tipo, como Currency, DateTime, etc..?.

¿Y qué pasa si necesitamos más clases? ¿Y el manejo de la herencia? ¿Y cómo tratamos las relaciones uno a varios? Y muchos otros puntos, todo a explorar en los siguientes post de la serie.

Mientras, algunos recursos:

Online NHibernate Documentation
NHibernate available resources
SourceForge project

Libro: Jason Dentler’s NHibernate 3.0 Cookbook

http://delicious.com/ajlopez/nhibernate+tutorial

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Leave a Reply

Your email address will not be published. Required fields are marked *