116
Hibernate 3 Ramiro González Sánchez Octubre del 2006

Hibernate 3

Embed Size (px)

Citation preview

Page 1: Hibernate 3

Hibernate 3

Ramiro González SánchezOctubre del 2006

Page 2: Hibernate 3

información confidencial

Contenido

Sesión 1El problema del mapeo Objeto/RelacionalPatrones de Diseño involucradosQuickStart

Sesión 2O/R MappingConsultasPersistencia

Sesión 3TransaccionesHibernate ToolsEvaluación

Page 3: Hibernate 3

El problema del mapeo Objeto/Relacional

Page 4: Hibernate 3

información confidencial

Partida

UML E/R

Un Modelo de Clases responde necesidades de modelado que no necesariamente satisfacen las reglas de normalización o integridad de un Modelo de Entidad-Relación.

Factura Partida

Factura Partida

Nada impide que unaPartida aparezca en 2Facturas.

Page 5: Hibernate 3

información confidencial

UML E/R

Adicionalmente, un Modelo de Clases posee mecanismos que no tienen una contraparte en E/R como: Herencia, Interfases y Relaciones bidireccionales, Multiplicidad muchos a muchos.

Factura

FacturaElectrónica

FacturaImpresa

Page 6: Hibernate 3

información confidencial

Labor tediosa

DAO BDValueObjectSQL

ResultSet

get…()ValueObject

ValueObject

Proceso Iterativo:{ get… get… get… }

Page 7: Hibernate 3

información confidencial

Problema n + 1

Los joins de tablas no tienen un mapeo “natural”.

Factura

Partida

Partida

Partida

Select *From Factura join Partida

Select *From Factura-- MergeSelect *From Partida

Select *From FacturaFetch {

Select *From Partida

}

Factura

Partida

Partida

Partida

Factura

Partida

Partida

Partida

Factura

Partida

Partida

Partida

Factura

Partida

Partida

Partida

?

Page 8: Hibernate 3

información confidencial

Otros problemas

Caching de Objetos: Problema de igualdad.Objetos compartidosObjetos bloqueadosTransacciones sobre objetos

Page 9: Hibernate 3

información confidencial

El mundo ideal…

Factura f = new Factura();f.add(new Partida());domainStore.save(f); //insert into Factura; insert into Partida//commit

//

f = query.find(Factura, 12345);// select * from Factura where id = 12345;// select * from Partida where id = 12345;f.removePartida(1);// delete from Partida where …domainStore.save(f);

Page 10: Hibernate 3

Patrones de Diseño involucrados

Page 11: Hibernate 3

información confidencial

Data Access Object

Page 12: Hibernate 3

información confidencial

Domain Store

Clases de Negocio

AdministradorDe

Persistencia

AdministradorDe

Persistencia

BD

Mapeo

Page 13: Hibernate 3

QuickStart

Page 14: Hibernate 3

información confidencial

Ambiente utilizado para el Curso

Windows XP Professional Edition Service Pack 2J2SE Development Kit v. 1.5.0_04Eclipse SDK 3.1.2MyEclipse IDE v. 4.1.1 GAJBoss 4.0.3 SP1PostgreSQL v. 8.1

Windows XP Professional Edition SP2Windows XP Professional Edition SP2

J2SE Development Kit 1.5.0_06J2SE Development Kit 1.5.0_06

Eclipse SDK 3.1.2Eclipse SDK 3.1.2

MyEclipse 4.1.1 GAMyEclipse 4.1.1 GA

Page 15: Hibernate 3

información confidencial

Descargar

ftp://ssdesa01usuario: cursoPassword: curso

Page 16: Hibernate 3

información confidencial

Estructura del Ambiente de Desarrollo

MyEclipseMyEclipse

EclipseEclipse

DeploymentServices

Plugins DB Explorer

JBossJBoss

Java Virtual MachineJava Virtual Machine

Java Virtual MachineJava Virtual Machine

PostgreSQL8.1

Page 17: Hibernate 3

información confidencial

Verificación de Ambiente

JDKVariable de entorno JAVA_HOME válida%JAVA_HOME%\bin en el PATHEjecutar en línea de comandos java -version

Page 18: Hibernate 3

información confidencial

Verificación de Ambiente

MyEclipseVerificar que existe el menú y qué arranca con la correcta versión.

Page 19: Hibernate 3

información confidencial

Verificación de Ambiente

JBossLocalizar la carpeta donde está instalado (usualmente C:\Java\jboss-4.0.3SP1)A esta carpeta le llamaremos de ahora en adelante JBOSS_HOMEPosicionarse en línea de comandos en:

%JBOSS_HOME%\binY ejecutar el comando: run.bat

Page 20: Hibernate 3

información confidencial

Verificando el Ambiente

PostgreSQL

Page 21: Hibernate 3

información confidencial

Arrancar la Base de Datos

Page 22: Hibernate 3

información confidencial

Crear Base de Datos

Page 23: Hibernate 3

información confidencial

Tabla de Prueba

Page 24: Hibernate 3

información confidencial

Nuevo Proyecto

Page 25: Hibernate 3

información confidencial

Configuración del Proyecto Java

Page 26: Hibernate 3

información confidencial

Finalizando la configuración

Page 27: Hibernate 3

información confidencial

Configuración de una conexión

Page 28: Hibernate 3

información confidencial

Edición del driver

Page 29: Hibernate 3

información confidencial

Agregando el Driver

Page 30: Hibernate 3

información confidencial

Driver configurado

Page 31: Hibernate 3

información confidencial

Configuración de un Profile de Conexión

Page 32: Hibernate 3

información confidencial

Finish…

Page 33: Hibernate 3

información confidencial

Abriendo la Conexión

Page 34: Hibernate 3

información confidencial

Abrir Conexión…

Page 35: Hibernate 3

información confidencial

Habilitando Hibernate en nuestro proyecto

Page 36: Hibernate 3

información confidencial

Configuración de Hibernate

Page 37: Hibernate 3

información confidencial

Creación de la Configuración

Page 38: Hibernate 3

información confidencial

Creación de un SessionFactory

Page 39: Hibernate 3

información confidencial

Interfases Hibernate

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDjdbc

Cfg(xml)

Page 40: Hibernate 3

información confidencial

Elementos Creados

SessionFactory Hibernate.cfg.xml Mappings.hbm.xmlMappings.hbm.xmlMappings.hbm.xml

Session ClasesPersistentes

ClasesPersistentesClases

PersistentesClasesPersistentes

Clase Aplicativa

curr

entS

essi

on()

<<uses>>

<<uses>>

<<uses>>

Query

Page 41: Hibernate 3

información confidencial

Configuración de la Conexión en Hibernate

Page 42: Hibernate 3

información confidencial

Conexión en Hibernate

Page 43: Hibernate 3

información confidencial

Mapping de 1 tabla

Page 44: Hibernate 3

información confidencial

ID Generator

Page 45: Hibernate 3

información confidencial

Mapping insertado

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->

<hibernate-configuration>

<session-factory>

<property name="myeclipse.connection.profile">qshibernate</property>

<propertyname="connection.url">jdbc:postgresql://localhost:5432/testHibernate</property>

<property name="connection.username">postgres</property>

<property name="connection.password">notiene</property>

<property name="connection.driver_class">org.postgresql.Driver</property>

<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

<mapping resource="mx/com/ids/qshibernate/Mensajes.hbm.xml" />

</session-factory>

</hibernate-configuration>

Page 46: Hibernate 3

información confidencial

Código Generado

Page 47: Hibernate 3

información confidencial

Log4J

Hibernate utiliza Log4J para enviar sus mensajes de Log.Por lo que se requiere adicionalmente insertar la configuración de Log4j en el classpath:

log4j.logger.org.hibernate.ce=infolog4j.logger.org.hibernate=info

### log HQL query parser activity#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQLlog4j.logger.org.hibernate.SQL=info

### log JDBC bind parameters ####log4j.logger.org.hibernate.type=debug

Page 48: Hibernate 3

información confidencial

Obtención de la Conexión

public static Session currentSession() throws HibernateException {Session session = (Session) threadLocal.get();

if (session == null) {if (sessionFactory == null) {

try {cfg.configure(CONFIG_FILE_LOCATION);sessionFactory = cfg.buildSessionFactory();

}catch (Exception e) {

System.err.println("%%%% Error CreatingSessionFactory %%%%");

e.printStackTrace();}

}session = sessionFactory.openSession();threadLocal.set(session);

}return session;

}

Page 49: Hibernate 3

información confidencial

Prueba

public static void main(String[] args) {// Step 1 - Create a new entityMensajes message = new Mensajes();// Step 2 - Set message fieldmessage.setTexto("Hello Hibernate, from MyEclipse!");

try {// Step 3 - Get a Hibernate SessionSession session = HSessionFactory.currentSession();// Step 4 - Persist entity to databaseTransaction tx = session.beginTransaction();session.save(message);tx.commit();System.out.println("Save successful.");

} catch (HibernateException e) {System.out.println("Save failed.");

} finally {try {

// Step 5 - close the sessionHSessionFactory.closeSession();

} catch (HibernateException e1) {// do nothing

}}

}

Page 50: Hibernate 3

información confidencial

2005-11-10 22:40:49,390 [main] INFO org.hibernate.impl.SessionFactoryImpl -Checking 0 named queries2005-11-10 22:40:49,468 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 42P012005-11-10 22:40:49,468 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: relation "hibernate_sequence" does not existSave failed.

Page 51: Hibernate 3

información confidencial

Especificando el nombre de la secuencia

<id name="id" column="id" type="java.lang.Integer"><generator class="native"><param name="sequence">

mensajes_id_seq</param>

</generator></id>

2005-11-10 22:51:05,328 [main] INFO org.hibernate.impl.SessionFactoryImpl -Checking 0 named queriesSave successful.

Page 52: Hibernate 3

información confidencial

Resultado en la base de datos

Page 53: Hibernate 3

información confidencial

Prueba 2

public static void main(String[] args) {try {

// Step 1 - Get a Hibernate SessionSession session = HSessionFactory.currentSession();// Step 2 - Crea un queryQuery q = session.createQuery("from Mensajes");

String qSQL = q.getQueryString();System.out.println("Query: " + qSQL);

// Step 3 - Ejecuta el queryList l = q.list();

for (Iterator iter = l.iterator(); iter.hasNext();) {Mensajes element = (Mensajes) iter.next();System.out.println(element.getId() + ":" +

element.getTexto());}

} catch (HibernateException e) {

Page 54: Hibernate 3

información confidencial

Prueba 3

public static void main(String[] args) {try {

// Step 1 - Get a Hibernate SessionSession session = HSessionFactory.currentSession();// Step 2 - Crea un query con parametroQuery q = session.createQuery("from Mensajes where id

= :pId");

// Step 3 - Indica el parametroq.setInteger("pId", 1);

// Step 4 - Ejecuta el queryList l = q.list();String qSQL = q.getQueryString();System.out.println("Query: " + qSQL);

for (Iterator iter = l.iterator(); iter.hasNext();) {Mensajes element = (Mensajes) iter.next();System.out.println(element.getId() + ":" +

element.getTexto());}

} catch (HibernateException e) {

Page 55: Hibernate 3

O/R Mapping

Page 56: Hibernate 3

información confidencial

Modos de Operación

Administrado y No Administrado

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDjdbcConnectionPool

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDDatasource

TransactionManager

ResourceManager

Page 57: Hibernate 3

información confidencial

Propiedades útiles en hibernate.cfg.xml

show_sql = truehibernate.default_schema = ESQUEMAX

Page 58: Hibernate 3

información confidencial

Modelo de Pruebas

Factura Partida

Cliente

Producto

Partida

Page 59: Hibernate 3

información confidencial

Escritura de POJO’s

Deben Implementar SerializableImplementar un constructor vacío

Page 60: Hibernate 3

información confidencial

Escritura de POJO’s

Declarar los métodos set y get de cada propiedad/columna excepto la llave primaria.

Page 61: Hibernate 3

información confidencial

Escritura de POJO’s

El tipo de la llave primaria puede ser una clase auxiliar para manejar el caso de llave compuesta.

Page 62: Hibernate 3

información confidencial

Escritura de POJO’s

Los campos que representan llaves foráneas deben ser declarados con el tipo de la Clase que representa la entidad foránea.

Page 63: Hibernate 3

información confidencial

Asociaciones Bidireccionales

De la Factura al Cliente se puede navegar con la declaración de la columna Cliente en Factura. La operación inversa requiere de declarar un Set de facturas en el cliente.

/** The value of the facturaSet one-to-many association. */private java.util.Set facturaSet;

…public java.util.Set getFacturaSet()

{return this.facturaSet;

}

public void setFacturaSet(java.util.Set facturaSet){

this.facturaSet = facturaSet;}

Page 64: Hibernate 3

información confidencial

Cliente.hbm.xml

DTD

Paquete

Clase

PK

Asociación

Page 65: Hibernate 3

información confidencial

Factura.hbm.xml

FK

Page 66: Hibernate 3

información confidencial

Partida.hbm.xml

LlaveCompuesta

Llave foránea dentro de Llave

Compuesta

Page 67: Hibernate 3

información confidencial

Opciones de ID’s

nativeidentitysequence

assigned

Page 68: Hibernate 3

Consultas

Page 69: Hibernate 3

información confidencial

get()

int clienteId=1;

Cliente cliente = (Cliente) session.get(Cliente.class, new Long(clienteId);

Si el clienteId solicitado no existe, get() regresa null.

Page 70: Hibernate 3

información confidencial

Navegando por el Grafo

Una vez cargado un objeto… es posible obtener el resto... siempre y cuando la sesión siga abierta.

Cliente cliente = partida.getFactura().getCliente();

Page 71: Hibernate 3

información confidencial

Mediante HQL

Query query = session.createQuery(“from Cliente c where c.email like ‘%ids.com.mx’ ”);List l = query.list();

Esto es idéntico a:

List l = session.find(“from Cliente c where u.email like ‘%ids.com.mx’ ”);

Page 72: Hibernate 3

información confidencial

Utilizando SQL Nativo

Query query = session.createQuery(“Select mx.com.ids.qshibernate.Cliente(*)from Cliente where id = :pId”);

List l = query.list();

Page 73: Hibernate 3

información confidencial

Query by Criteria

Criteria criteria = session.createCriteria(Cliente.class);criteria.add( Expression.like(“email”, “%ids.com.mx”);criteria.addOrder(Order.asc(“paterno”);

List l = criteria.list();

Page 74: Hibernate 3

información confidencial

Query by Example

Cliente clienteX = new Cliente();clientex.setNombre(“Juan”);

Criteria criteria = session.createCriteria(Cliente.class);criteria.add( Example.create(clienteX) );

List l = criteria.list();

Page 75: Hibernate 3

información confidencial

Paginación

Utilizando un objeto Query o Criteria

query.setFirstResult(41);query.setMaxResults(20);

Page 76: Hibernate 3

información confidencial

Leyendo 1 solo renglón

query.setMaxResult(1);

query.uniqueResult();

Page 77: Hibernate 3

información confidencial

Manejo de parámetros

Por nombre(“from Cliente where id = :pId);

Por posición(“from Cliente where nombre = ? and paterno = ?”);La primera posición es 0.

Page 78: Hibernate 3

información confidencial

Estrategias de Fetching

Immediate FetchingInmediato (1 por 1)

Lazy FetchingEn el primer acceso (por default)

Eager FetchingEl objeto y sus relaciones

Batch FetchingLectura en lotes (merge)

Page 79: Hibernate 3

información confidencial

Estrategia de Acceso

Se puede declarar en el mapeo o durante tiempo de ejecución.

En el mapeo se maneja por Asociación y se tienen 3 parámetros:

lazy = “true” o “false”outer-join = “true” o “false”batch-size = “9”

En una clase solo puede haber una asociación con outer-join=“true”

Page 80: Hibernate 3

información confidencial

Profundidad del Fetch

Se debe controlar la profundidad de los joins:hibernate.max_fetch_depth=1,2,3…

Utilizar máximo a 4.

Page 81: Hibernate 3

información confidencial

Eager Fetching

Por default, se usa lazy loading…

Para provocar el eager fetching en tiempo de ejecuciónse describe la intención en el query:

from Factura fleft join fetch f.partidaSet

Page 82: Hibernate 3

información confidencial

Theta-join

Se utiliza en tablas que no tienen una asociación definida

from User user, LogRecord logwhere user.username = log.username

Esto devuelve pares de los objetos referenciados:

while( i.hasNext() ) {Object[] pair = (Object []) i.next();User user = (User) pair[0];LogRecord log = (LogRecord) pair[1];

}

Page 83: Hibernate 3

información confidencial

Report Queries

Tabular

select item.id, item.descriptionorder by item.id

retorna Object[];

Mediante Objeto predefinido

select new Renglon( item.id, item.description )order by item.id

Renglon, debe ser una clase con el constructor apropiado.

Page 84: Hibernate 3

información confidencial

Named Queries

En el mapping de la tabla principal:

<sql-query name=“findClientesFacturas”><![CDATA[

select {c.*}, {f.*}from cliente c inner join factura fwhere c.id = f.idcliente

]]><return alias=“c” class=“Cliente” /><return alias=“f” class=“Factura” /></sql-query>

Nota: También funciona para HQL con la etiqueta “query”.

Page 85: Hibernate 3

Persistencia

Page 86: Hibernate 3

información confidencial

Ciclo de Vida de un Objeto

Page 87: Hibernate 3

información confidencial

Creando un objeto persistente

Cliente cliente = new Cliente();

cliente.setNombre(“Juan”);cliente.setPaterno(“Perez”);cliente.setEmail(“[email protected]”);

Session session = QSSessionFactory.currentSession();Transaction tx = session.beginTransaction();

session.save(cliente);tx.commit();session.close();

Page 88: Hibernate 3

información confidencial

Actualización de Detached con Update

cliente.setMaterno(“Perez”);

Session session = QSSessionFactory.currentSession();Transaction tx = session.beginTransaction();

session.update(cliente);

cliente.setEmail(“[email protected]”);

tx.commit();session.close();

Cualquier objeto asociado a la base

de datos, se actualiza

automáticamente.

Page 89: Hibernate 3

información confidencial

Actualización con Lock

cliente.setMaterno(“Perez”);

Session session = QSSessionFactory.currentSession();Transaction tx = session.beginTransaction();

session.lock(cliente, LockMode.NONE);

cliente.setEmail(“[email protected]”);

tx.commit();session.close();

READUPGRADE

Page 90: Hibernate 3

información confidencial

Borrado de un Objeto

session.delete(objeto)

Page 91: Hibernate 3

información confidencial

Ejercicio

Instale el ambiente de desarrolloJDKPostgreSQLEclipseMyEclipse

Cree una base de datos con PGAdminIIICorra el script creaTestHibernate.sqlGenere el proyecto configurado para HibernateGenere los mappings de las tablas recién creadasEscriba código que

Inserte 2 clientes nuevosInserte 2 productos nuevosInserte 1 factura a cada cliente con su respectiva partida y referenciando a 1 productoListe los clientes con sus facturas con sus partidas con sus productos

Page 92: Hibernate 3

Transacciones

Page 93: Hibernate 3

información confidencial

Manejo de Transacciones

La estructura de código estándar y recomendada es la siguiente:

Page 94: Hibernate 3

información confidencial

Transacciones dentro del Contenedor J2EE

HibernateHibernate

Session

Transaction

Query

AplicaciónJava

BDDatasource

TransactionManager

ResourceManager

hibernate.transaction.factory_class = org.hibernate.transaction.JTATransactionFactoryhibernate.transaction.manager_lookup_class = <dependiente del Application Server>

Page 95: Hibernate 3

información confidencial

JTA Transaction Manager

Borland ESorg.hibernate.transaction.BESTransactionManagerLookup

JRun4org.hibernate.transaction.JRun4TransactionManagerLookup

JOnASorg.hibernate.transaction.JOnASTransactionManagerLookup

JOTMorg.hibernate.transaction.JOTMTransactionManagerLookup

Resinorg.hibernate.transaction.ResinTransactionManagerLookup

Orion/OC4J/OracleASorg.hibernate.transaction.OrionTransactionManagerLookup

WebSphere 6org.hibernate.transaction.WebSphereExtendedJTATransactionLookup

WebSphereorg.hibernate.transaction.WebSphereTransactionManagerLookup

Weblogicorg.hibernate.transaction.WeblogicTransactionManagerLookup

JBossorg.hibernate.transaction.JBossTransactionManagerLookup

Page 96: Hibernate 3

Hibernate Tools

Page 97: Hibernate 3

información confidencial

Conversión entre Modelos

UML (XMI)UML (XMI)

POJO’sPOJO’s

O/R MappingO/R Mapping

DDLDDL

AndroMDA

Xdoclet

hbm2ddl Middlegen

hbm2java

ReverseEngineering

Page 98: Hibernate 3

información confidencial

Instalación de Hibernate Tools

Simplemente se desempaca el paquete que contiene los Hiberneta Tools en el directorio de Eclipse.

Page 99: Hibernate 3

información confidencial

Nuevo proyecto Java…

Page 100: Hibernate 3

información confidencial

Configuración Proyecto Java

Page 101: Hibernate 3

información confidencial

Nuevo Java Package

Page 102: Hibernate 3

información confidencial

Nuevo Hibernate Configuration File

Page 103: Hibernate 3

información confidencial

Create Hibernate Console Configuration

Page 104: Hibernate 3

información confidencial

Verificando

Page 105: Hibernate 3

información confidencial

Artifact Generation

Page 106: Hibernate 3

información confidencial

Configuración de Artifact Generation

Page 107: Hibernate 3

información confidencial

Setup Reverse Engineering

Page 108: Hibernate 3

información confidencial

Selección de carpeta y nombre

Page 109: Hibernate 3

información confidencial

Include… Exclude…

Page 110: Hibernate 3

información confidencial

Configuración final

Page 111: Hibernate 3

información confidencial

Confirmación…

Page 112: Hibernate 3

información confidencial

Artefactos Generados

Page 113: Hibernate 3

información confidencial

HQL Editor

Page 114: Hibernate 3

información confidencial

Modelo Relacional

Page 115: Hibernate 3

información confidencial

Preguntas…

Page 116: Hibernate 3

información confidencial

Referencias

Hibernate in ActionChristian Bauer, Gaving KingManning(disponible en pdf)

www.hibernate.orgDownloads, documentación de referencia.

http://caveatemptor.hibernate.orgAplicación demo de hibernate

Sun J2EE Patterns Cataloghttp://java.sun.com/blueprints/patterns/catalog.html