Observatorio de Grails 
  • Inicio
  • Actualidad
  • Artículos
  • Tutoriales
  • Eventos
  • Foro
  • Acerca de
Conocer cuándo se modifican mis datos Exprimiendo el belongsTo con múltiples relaciones bidireccionales
mar 04

¿Clave ajena u otra tabla adicional en relaciones 1:M?

publicado por Enrique Medina Montenegro

1 comentario
1.597 visitas
(5 votos, media: 4,20)

Enrique Medina Montenegro

Twitter  |  LinkedIn

Con más de 14 años de experiencia en el mundo de las TI, donde comenzó desarrollando aplicaciones de escritorio en Delphi o Visual Basic, este Ingeniero en Informática por la Universidad de Alicante (1991-1996) ha ido perfilando su actividad profesional hacia las arquitecturas J2EE, donde siempre ha seguido muy atento, e incluso colaborado en ocasiones, con proyectos open-source como MyFaces, Spring, Hibernate, Groovy o Grails. Ocupando puestos desde Programador Junior hasta Arquitecto Senior de Soluciones, Enrique ha sido testigo de cómo ha ido evolucionando la tecnología en torno al desarrollo de aplicaciones web, adquiriendo un conocimiento y experiencia que le permiten evaluar con detalle las necesidades de cada proyecto y aplicar las herramientas que maximizan su productividad. Actualmente, Enrique se ha especializado en el framework de desarrollo Grails, y ejerce la Dirección Técnica de proyectos basados, entre otras, en esta tecnología.

He de reconocer que cuando estudiaba en la universidad y, en particular, asistía a las clases de “Gestión de Bases de Datos“, se me daba muy bien; ¿por qué?, pues porque disfrutaba normalizando mis modelos. Qué recuerdos, ¿verdad? Pero cuando tuve que enfrentarme al mercado laboral, es decir, buscar curro, me di cuenta de que no todo el monte es orégano, claro. Y aquel púlpito en que me sentaba cada vez que comenzaba a diseñar un esquema relacional de bases de datos (BD) comenzó a derrumbarse poco a poco, proyecto a proyecto.

Un ejemplo muy claro es la denormalización que prácticamente debemos aplicar en cada proyecto, porque está muy bien eso de que una relación M:N siempre genere una entidad nueva, y que una relación 1:M defina una clave ajena en el lado del M que apunta a la entidad del lado del 1. Pero, ¿qué pasa si tenemos requisitos especiales que, en caso de atarnos a un modelo completamente normalizado, no hacen más que añadir complejidad y quebraderos de cabeza? En estos casos, de nuevo, Grails acude en nuestra ayuda permitiéndonos influir en la manera en que GORM genera y crea posteriormente las tablas y sus relaciones en BD. Veamos cómo mediante ejemplos en el caso de relaciones 1:M.

Con clave ajena

Este es el comportamiento “esperado” cuando creamos una relación 1:M entre dos entidades:

class Padre {

	String nombre
	String apellidos

	static hasMany = [hijos: Hijo]

}

class Hijo {

	String nombre
	String apellidos
	int edad

	static belongsTo = [padre: Padre]

La clase Padre sería el lado del 1, mientras que la clase Hijo estaría en el lado de la M, como se deduce del código arriba. Si generamos las sentencias DDL a partir de esta configuración (grails schema-export), obtendremos:

alter table hijo drop constraint FK30DE06336F7BDA;
drop table hijo if exists;
drop table padre if exists;
create table hijo (id bigint generated by default as identity (start with 1), version bigint not null, nombre varchar(255) not null, apellidos varchar(255) not null, edad integer not null, padre_id bigint not null, primary key (id));
create table padre (id bigint generated by default as identity (start with 1), version bigint not null, nombre varchar(255) not null, apellidos varchar(255) not null, primary key (id));
alter table hijo add constraint FK30DE06336F7BDA foreign key (padre_id) references padre;

Lo esperado, ¿no?

Generando una nueva entidad (al estilo del M:N)

Si queremos seguir teniendo una relación 1:M, pero que se genere una nueva entidad donde se mantenga la relación, en vez de a través de una clave ajena, podemos definir:

class Padre {

	String nombre
	String apellidos

	static hasMany = [hijos: Hijo]

}

class Hijo {

	String nombre
	String apellidos
	int edad

	static belongsTo = Padre

Si se compara este código con el del caso anterior, vemos que lo único que cambia es la definición del belongsTo en la clase Hijo. Pues bien, este simple cambio indica a GORM que genere una entidad adicional que mantenga la relación; de nuevo, si generamos el SQL, ahora obtenemos:

alter table padre_hijo drop constraint FKE250849F8BF9CB6C;
alter table padre_hijo drop constraint FKE250849F36E0E01A;
drop table hijo if exists;
drop table padre if exists;
drop table padre_hijo if exists;
create table hijo (id bigint generated by default as identity (start with 1), version bigint not null, nombre varchar(255) not null, apellidos varchar(255) not null, edad integer not null, primary key (id));
create table padre (id bigint generated by default as identity (start with 1), version bigint not null, nombre varchar(255) not null, apellidos varchar(255) not null, primary key (id));
create table padre_hijo (padre_hijos_id bigint, hijo_id bigint);
alter table padre_hijo add constraint FKE250849F8BF9CB6C foreign key (padre_hijos_id) references padre;
alter table padre_hijo add constraint FKE250849F36E0E01A foreign key (hijo_id) references hijo;

Curioso, ¿no?
Quede claro que aquí no aconsejamos el uso de ni una ni la otra posibilidad cuando se trabaje con relaciones 1:M; nuestro único propósito es el de dar a conocer las posibilidades que GORM nos ofrece y dejar al buen criterio del desarrollador la elección de la que más se ajuste a su proyecto.

Del.icio.us Facebook LinkedIn Twitter

  1. jose
    04/11/2011 a las 14:08

    Y que pasa si en la tabla Hijo tb quiero que nombre sea clave primaria?

    Saludos

Escribir un comentario

Clic para cancelar respuesta.

Actualidad  Entradas relacionadas  si te ha interesado la entrada te proponemos otras lecturas relacionadas

  • mar15

    Cómo establecer un valor iniciar a una clave primaria (inglés)

    publicado por Enrique Medina Montenegro en Grails

    0 comentarios
    275 visitas
    (1 votos, media: 3,00)
  • may31

    Creación de formularios padre-hijo con Vaadin y Grails (inglés)

    publicado por Alberto J. Hormigo en Grails

    0 comentarios
    755 visitas
    (2 votos, media: 4,50)

Comentarios recientes  Comentarios recientes

  • pedro luis hola como cargo imágenes de un archivo para mostrarlo en un reporte con los demás datos; en Reportes en Grails con iReport
    17/05/2012 a las 21:03

  • yo 123; en Clusterizar una aplicación Grails con EhCache (inglés)
    24/04/2012 a las 17:33

  • yo muy buebo; en Clusterizar una aplicación Grails con EhCache (inglés)
    24/04/2012 a las 17:21

Twitter  

preload preload preload

Síguenos en Twitter  |  Facebook
Inicio  |  Actualidad  |  Artículos  |  Tutoriales  |  Eventos  |  Foro  |  Acerca de

© 2010 Observatorio de Grails. Todos los derechos reservados.