Professional Documents
Culture Documents
una ventaja que ofrecen los frameworks es que permiten manejar las
referencias lazy realizando consultas mientras la sesin est activa. Ej: si
estoy buscando los clientes que comiencen con Q, pero despus quiero
obtener el total que sale de conocer el saldo de todas las facturas pendientes,
al hacer
facturas.fold (0, [acum, factura | acum + factura.saldo ])
en ese momento se dispara la consulta a las facturas de un cliente y as
sucesivamente.
construir los queries de consulta en el lenguaje que cada framework ofrece
32 de 37
Diseo de Sistemas Mapeo Objetos Relacional
manejar los errores que ocurran en los llamados hacia el motor de base de datos (en
la mayora de los casos no habr mucho para hacer ms que generar una excepcin
de ms alto nivel para avisar al usuario de que la consulta fall)
Mostramos un ejemplo en Xtend, utilizando Annotations para mapear una relacin
muchos a muchos entre Profesor y Materia (un profesor puede dar muchas materias y
una materia tiene muchos profesores):
@Entity
class Profesor implements Serializable {
@Id
@GeneratedValue
@Property private Long id
@Column
@Property private String nombreCompleto
@ManyToMany(fetch = FetchType.LAZY)
@Property private Set<Materia> materias
// Lo necesita Hibernate
new() {
}
...
@Entity
class Materia {
@Id
@GeneratedValue
@Property private Long id
@Column
@Property private String nombre
@Column
@Property private int anio
// Lo necesita Hibernate
new() {
}
...
Esto define tres entidades:
33 de 37
Diseo de Sistemas Mapeo Objetos Relacional
Profesor
Materia
Profesor_Materia con referencias a las claves primarias de profesor y materia
Ejemplo: si queremos reflejar que el profesor Lucas Spigariol da Paradigmas y
Algoritmos y Estructura de Datos...
Materia
ID NOMBRE ANIO
1 Paradigmas de Programacin 2
2 Algoritmos y Estructura de Datos 1
Profesor
ID NOMBRE_COMPLETO
1 Lucas Spigariol
2 Leonardo Gassman
Materia_Profesor
PROFESOR_ID MATERIA_ID
1 1
1 2
Vemos la consulta que resuelve qu profesores dan una materia determinada:
def getProfesores(Materia materia) {
var List<Profesor> result = null
val session = sessionFactory.openSession
try {
result = session
.createCriteria(typeof(Profesor))
.createAlias("_materias", "materias")
.add(Restrictions.eq("materias.id", materia.id))
.list
} catch (HibernateException e) {
throw new RuntimeException(e)
} finally {
session.close
}
34 de 37
Diseo de Sistemas Mapeo Objetos Relacional
result
}
Para ms informacin recomendamos leer http://www.hibernate.org/
Data Mapper vs. Active Record
Data Mapper: en nuestros ejemplos hemos utilizado la estrategia de tener
un repositorio, un objeto que sirve como una entidad mapeadora del modelo
relacional y el de objetos.
Active Record: otro approach que se populariz a partir de frameworks como
Ruby on Rails, Grails, etc. es decorar a los objetos de dominio agregndoles las
responsabilidades de save(), update(), delete() y mtodos de clase que resuelvan
las bsquedas: findBy..., findAll, etc.
Vemos un ejemplo en Grails, que resuelve la consulta de libros por ttulo y autor, donde
le pedimos a la clase pelcula que cree un criterio de bsqueda al cual le enviamos el
mensaje list con un bloque que tiene las restricciones que aplican sobre ese query:
>>RepoPeliculas
@Transactional(readOnly=true)
def getPeliculas(titulo) {
Pelicula.createCriteria().list(max: 5) {
ilike("titulo" , "%" + titulo + "%")
}
}
35 de 37
Diseo de Sistemas Mapeo Objetos Relacional
Una pelcula tiene un gnero (una relacin many to one):
class Pelicula {
String titulo
Genero genero
String sinopsis
String actores
static constraints = {
titulo maxSize: 255
actores maxSize: 255
}
static mapping = {
sinopsis type: 'text'
}
O/R o R/O?
Una vez adoptada la decisin de trabajar con bases relacionales, la pregunta es qu hacer
primero:
1. Generamos el modelo relacional y luego adaptamos el modelo de objetos en base
a las tablas generadas
2. Generamos el modelo de objetos y en base a ste se crean las tablas.
La opcin 1) supone que es ms importante la forma en que guardo los datos que las
reglas de negocio que modifican esos datos. Pero a veces no nos queda otra chance, si
partimos de un sistema construido o enlatado. En la opcin 2) el desarrollo con objetos no
se ve ensuciado por restricciones propias de otra tecnologa.
Conclusiones
Persistir nuestro modelo de objetos en un esquema relacional requiere conocer cmo
funcionan ambos mundos y entender qu decisiones de diseo estn tras ese mapeo:
manejo de la identidad
las relaciones entre entidades
cardinalidad: uno a uno, uno a muchos, muchos a muchos
direccin: cmo navego el grafo de objetos y cunta informacin traigo en
cada pedido
relacionar los dominios de la base vs. los tipos que definen los objetos
cmo manejar las colecciones (orden y duplicados)
qu estrategia adoptar para los casos de generalizacin (herencia)
36 de 37
Diseo de Sistemas Mapeo Objetos Relacional
Pero adems, debemos definir la arquitectura que va a dar soporte a este mapeo,
adaptando la diferencia o impedance mismatch a mano o con frameworks de terceros. Y
por ltimo, debemos definir quin resuelve la conexin a la base, quin define el manejo
de la transaccin (cuando tenemos efecto colateral), quin dialoga con el framework o
con una API de bajo nivel contra la base, etc. Las opciones ms comunes son: separarlo
de los objetos de dominio y llevarlo a un objeto aparte (Repository, Home o DAO, Data
Mapper) o bien incluir dicha responsabilidad dentro del objeto de dominio decorado
(Active Record).
37 de 37