Mapeando relaciones y colecciones en hibernate Diciembre 2008
JosĂŠ A. GarcĂa jagarcia@siteframe.tk
Volvamos al ejemplo del Jueves public class Message { private Long id; private String text; private Message nextMessage; private Message() {} public Message(String text) { this.text = text; } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public String getText() { return text; }
public void setText(String text) { this.text = text; } public Message getNextMessage() { return nextMessage; } public void setNextMessage(Message nextMessage) { this.nextMessage = nextMessage; } }
2
Vimos como persistir un mensaje • La clase mensaje puede ser usada como cualquier otra clase Message message = new Message("Hello World"); System.out.println( message.getText() );
• Usamos hibernate para persistir los datos a la BBDD Session session = getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); Message message = new Message("Hello World"); session.save(message); tx.commit(); session.close();
3
En la base de datos … • El Código de traduce a insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values (1, 'Hello World', null)
4
Para recrear el objeto haríamos • newSession.load ( clase del objeto, idObj ) Session newSession = getSessionFactory().openSession(); Transaction newTransaction = newSession.beginTransaction(); Event loadedEvent = (Event)session.load(Event.class, e.getId()); System.out.println(loadedEvent.getName()); newTransaction.commit(); newSession.close();
5
Para ejecutar una query • Session.CreateQuery (“sentencia HSQL”) Session newSession = getSessionFactory().openSession(); Transaction newTransaction = newSession.beginTransaction(); List messages = newSession.createQuery("from Message as m order by m.text asc"); System.out.println( messages.size() + " message(s) found:" ); for ( Iterator iter = messages.iterator();iter.hasNext(); ) { Message message = (Message) iter.next(); System.out.println( message.getText() ); } newTransaction.commit(); newSession.close();
6
En la Base de Datos .. • se traduciría a: select m.MESSAGE_ID, m.MESSAGE_TEXT,m.NEXT_MESSAGE_ID from MESSAGES m order by m.MESSAGE_TEXT asc
NOTA: ES IMPORTANTE NOTAR LA DIFERENCIA ENTRE EL HSQL Y EL CODIGO SQL FINAL.
7
Ejercicio 2 (basico) Crea la tabla mensaje y su correspondiente secuencia. Inserta algunas filas y obten el mapeo de hibernate. Escribe el siguiente c贸digo:
8
Ejercicio 2 (basico) 多Que acabamos de hacer? 多Cuantas sentencias SQL ha lanzado Hibernate? Ojea el fichero de mapeo, donde estan las relaciones for叩neas? Veremos con mas detalle el mapeo de asociaciones ma単ana.
9
Recordemos las diferencias entre MR y MOO NO SE CONSIDERAN LAS CLASES NO PERSISTENTES Por ejemplo : La clase GestorVuelos no se persiste!
Recordemos las diferencias entre MR y MOO
NO SE CONSIDERAN LAS RELACIONES NO ESTRUCTURALES p.e: administrativo GENERA informes
Recordemos las diferencias entre MR y MOO
NO EXISTE LA HERENCIA: se originan entidades dĂŠbiles o especializaciones con discriminante
COPIA SECRETARIO
GERENTE
COMERCIAL
Categoría
Nombre Código
Docente Código
Nombre
Trabajador
Departamento ES
Área
Docente
Administrativo
Administrativo Categoría Código
Nombre
Departamento
Área
Representación de la generalización en MR • Representación de la generalización Método 1: 1. Crear una tabla para el {} de entidades de nivel más alto (atributos claves: a1, a2, …, am ) 2. Crear una tabla para cada {} de entidades de nivel más bajo (Atributos: b1, b2, …, bn) • Con: {b1, b2, …, bn} {a1, a2, …, am} columnas Persona (nombre, calle ciudad) Empleado (nombre, sueldo) Cliente ( nombre, límite _crédito)
Representación de la generalización en MR • Representación de la generalización Método 2: (si es disjunta y completa) 1. Crea una tabla para cada entidad del {} de entidades de nivel más alto con: {discriminante} {a1, a2, …, am} columnas 2. se crean tablas secundarias para las entidades de nivel mas bajo incluyendo la clave de la tabla mas alta: {b1, b2, …, bn}: atributos de la entidad {discriminante}: de la entidad de nivel más alto Empleado (nombre, calle, ciudad, sueldo, idpersona) Cliente ( nombre, calle, ciudad, límite _crédito, idpersona) Persona (id, nombre, calle, ciudad, tipo)
Mapear relaciones de herencia en Hibernate
Hibernate define 3 estrategias para mapear herencia: - Basada en una Ăşnica tabla para toda la jerarquia de clases - Basada en una tabla por cada subclase concreta - Basada en una tabla por cada subclase y un discriminante
16
una única tabla para toda la jerarquia de clases • Supongamos que tenemos una interfaz Payment (pago), implementada por las clases CreditCardPayment, CashPayment, ChequePayment (pago por tarjeta de crédito, efectivo y cheque respectivamente). El mapeo de "una tabla por jerarquía" se vería así:
17
una Ăşnica tabla para toda la jerarquia de clases
18
Basada en una tabla por cada subclase concreta â&#x20AC;˘ En este caso la herencia se implementa mediante un cruce (<joined-subclass>):
19
Basada en una tabla por cada subclase concreta
20
Basada en una tabla por cada subclase concreta y un discriminante â&#x20AC;˘ En este caso usamos juntos <subclass> y <join>:
21
Basada en una tabla por cada subclase concreta y un discriminante
22
Ejercicio
BASANDONOS EN EL EJEMPLO DE CLASE.. (ver ejemplo) • Supongamos las clases: – Mensaje de correo electronico
•Guardan además del texto del mensaje, el nombre del remitente y su direccion de email. – Mensaje Multimedia
•Pueden guardar además del texto del mensaje un enlace a una imagen y una referencia a un fichero multimedia (musica,video..) Definir las relaciones de herencia y su adecuado mapeo en Hibernate
23
Mapeo de integridad referencial â&#x20AC;˘ Supongamos la siguiente herencia:
24
Mapeo de integridad referencial • ¿Qué ocurre si de repente un profesor puede ser también alumno? (herencia solapada) • ¿Cómo se mapea ese tipo de herencia? • ¿Cómo se representaría en Java?
25
Mapeo de integridad referencial Lo correcto serĂa plantear el problema de manera diferente. Entonces tendrias que tener una clase Persona, con una propiedad que sea una lista de instancias de clase CondicionAcademica. Esa clase CondicionAcademica, tendria dos subclases, Profesor y Alumno.
26
MAPEOS DE ASOCIACIONES (foraneas) Una asociaci贸n (una clave ajena en el MR) genera una referencia a un objeto o una colecci贸n de objetos en Java. Para modelar este tipo de mapeos Hibernate incorpora las etiquetas: <one-to-many> <many-to-many>
27
MAPEO de asociaciones de MUCHOS a UNO Es el tipo mas común de asociación (una direccion-muchas personas, un dueño-muchos animales…) create table Person ( personId number not null primary key, addressId number not null … ) create table Address ( addressId number not null primary key … )
28
MAPEO de asociaciones de UNO a UNO El mapeo en este caso es practicamente idéntico, la única diferencia es la constraint de unicidad. create table Person ( personId number not null primary key, addressId number not null … ) create table Address ( addressId number not null primary key … )
29
MAPEO de asociaciones de UNO a MUCHOS Es un caso más inusual y da lugar a un mapeo a través de un colección. create table Person ( personId number not null primary key, … ) create table Address ( addressId number not null primary key, personId number not null … )
30
MAPEO de asociaciones de MUCHOS a MUCHOS Da lugar a una tabla intermedia y a un conjunto mapeado sobre la tabla. create table Person ( personId number not null primary key, â&#x20AC;Ś ) create table PersonAddress( personId number not null, addressId number not null) create table Address ( addressId number not null primary key, â&#x20AC;Ś )
31
MAPEO de asociaciones de MUCHOS a MUCHOS Da lugar a una tabla intermedia y a un conjunto mapeado sobre la tabla. create table Person ( personId number not null primary key, â&#x20AC;Ś ) create table PersonAddress( personId number not null, addressId number not null) create table Address ( addressId number not null primary key, â&#x20AC;Ś )
32
Ejercicio
Crear las tablas dueĂąo y animal del ejemplo del veterinario teniendo en cuenta la relacion foranea.
Mapear las tablas adecuadamente y realizar varias inserciones. Si aĂşn no es la hora del cafĂŠ.. Te atreves a contemplar el caso de herencia entre animal y mascota?.
33