Jonathan Leibiusky's Blog

martes, diciembre 20, 2005

NHibernate desmenuzado

Hace poco tuve que pensar en un mapeo de NHibernate que resuelva la siguiente problemática:
Una entidad está asociada a otra entidad X la cual no conozco directamente sino a través de una interfaz Y (una especie de asociación polimórfica relativamente común en diseños orietandos a objetos).
En un primer momento recurrí a lo que ya sabía e intenté resolverlo por ese lado, encontrando varias soluciones, pero todas agregaban complejidad y alteraciones al diseño de forma que se "ensuciaba".
Finalemente leyendo un poco más la documentación de NHibernate llegué al tipo de asociación de <any>.
Sincramente considero que la documentación al respecto es muy pobre y no alcanza para entender ese feature.
Con lo cual luego de una investigación pude descifrar el funcionamiento el cual pasaré a explicar para que quede al conocimiento público.
El mapeo de es similar al pero en lugar de llevar una sola columna para el código de la entidad asociada, tendrá una columna adicional en donde se almacenará un texto (al estilo del Discriminator) para diferenciar una entidad de otra.
Con lo cual paso a mostrar un ejemplo:

<class name="ClaseA" table="ClasesA">
<id name="id" column="Codigo" type="Int32" value="-1">
<generator class="native" />
</id>
<any name="entidadRelacionada" type="String">
<meta-value value="ClaseB" class="ClaseB" />
<meta-value value="ClaseC" class="ClaseC" />
<column name="TipoEntidadTramite" />
<column name="CodigoEntidadTramite" />
</any>
</class>
La explicación línea por línea del nodo sería:

<any name="entidadRelacionada" type="String">

El name indica (como siempre) el field que contendrá la relación en la clase que estamos mapeando.
Luego el meta-type indica de qué tipo será la columna que almacenará el tipo de cada entidad que pueda relacionarse.
Por último el id-type indica de qué tipo será la columna que contendrá el código de la entidad relacionada.

<meta-value value="ClaseB" class="ClaseB">
<meta-value value="ClaseC" class="ClaseC">


Se pondrá un meta-value por cada entidad que pueda relacionarse con la clase y almacenarse en ese field. En el value iría el "discriminator" que le asignamos a la clase (es la forma con la que NHibernate diferencia las clases y sabe cómo instanciarlas, etc). Y luego con class se specifica finalmente a cuál clase nos estamos refiriendo.

<column name="TipoEntidadTramite">
<column name="CodigoEntidadTramite">

Por último se deben difinir de forma ordenada la columna que contendrá el tipo de entidad relacionada (con el valor del meta-value definido anteriormente según corresponda) y luego la columna que contendrá el código de aquella entidad.

Espero que se haya entendido. No es sencillo ya que no es una forma de asociación muy común. Pero les aseguro que es muy útil y sirve para evitar bastantes dolores de cabeza.

2 Comments:

Publicar un comentario

<< Home