En PostgreSQL, para que una tabla tenga un campo autoincrementable se puede usar SERIAL o BIGSERIAL, éstos últimos en realidad no son tipos de datos reales puesto que internamente se crean secuencias para los campos que usan esta sintáxis, por ejemplo:
id serial NOT NULL,
name character varying,
description character varying
);
Tabla «public.blog_category»
Columna | Tipo | Modificadores
-------------+-------------------+------------------------------------------------------------
id | integer | not null default nextval('blog_category_id_seq'::regclass)
name | character varying |
description | character varying |
Para representar representar esa tabla en NHibernate, hay que hacer algo adicional a lo que normalmente se hace con otro tipo de bases de datos:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Buayacorp.Domain.BlogCategory, Buayacorp.Domain" table="Blog_Category">
<property name="Name" type="String">
<column name="Name" length="255" sql-type="varchar"/>
</property>
<property name="Description" type="String">
<column name="Description" length="3000" sql-type="varchar"/>
</property>
<bag name="Blogs" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="category_id"/>
<one-to-many class="Buayacorp.Domain.Blog, Buayacorp.Domain"/>
</bag>
</class>
</hibernate-mapping>
En las líneas resaltadas se puede apreciar que para mapear el campo id
es necesario especificar el nombre de la secuencia definida en la base de datos, esto es porque para generar los nuevos valores para ese campo se usa la función nextval, que justamente toma como parámetro ese nombre. Por ejemplo, para la siguiente porción de código:
using System.Collections.Generic;
using System.Text;
using NHibernate.Cfg;
using NHibernate;
using Buayacorp.Domain;
using System.Xml;
namespace Buayacorp.Demo
{
static class Program
{
static void Main()
{
Configuration cfg = new Configuration();
cfg.AddAssembly("Buayacorp.Domain");
ISessionFactory factory = cfg.BuildSessionFactory();
ISession session = null;
ITransaction transaction = null;
try
{
session = factory.OpenSession();
transaction = session.BeginTransaction();
BlogCategory cat = new BlogCategory("Tecnología", "Blogs con información sobre lo último en tecnología...");
session.Save(cat);
Console.WriteLine(cat.Id); // cat.Id ya tiene un valor generado
transaction.Rollback();
}
finally
{
if (session != null)
session.Close();
}
}
}
}
Las consultas que se ejecutan en el servidor de base de datos son:
2007-04-22 17:44:38 PET LOG: sentencia: BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
2007-04-22 17:44:38 PET LOG: sentencia: ROLLBACK
2007-04-22 17:44:38 PET LOG: sentencia: unlisten *
Para los curiosos, pueden descargar el archivo que contiene el código mostrado en esta entrada.
One reply on “Mapeo de secuencias de PostgreSQL en NHibernate”
Alex:
El ejemplo esta bueno, pero si me lo podias enviar a mi correo el ejemplo, por que baje intronhibernate.zip y al momento de descomprimir me sale error "que no se puede abrir el archivo".
Muchas gracias