Está en la página 1de 116

Hibernate 3

Ramiro González Sánchez


Octubre del 2006
Contenido

Sesión 1
El problema del mapeo Objeto/Relacional
Patrones de Diseño involucrados
QuickStart
Sesión 2
O/R Mapping
Consultas
Persistencia
Sesión 3
Transacciones
Hibernate Tools
Evaluación

información confidencial
El problema del mapeo
Objeto/Relacional
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.

Nada impide que una


Factura Partida Partida aparezca en 2
Facturas.

Factura Partida

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
Electrónica

Factura

Factura
Impresa

información confidencial
Labor tediosa

ValueObject
ValueObject SQL
get…() DAO
ValueObject BD
ResultSet

Proceso Iterativo:
{ get… get… get… }

información confidencial
Problema n + 1

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

Select *
Partida From Factura join Partida
Select *
Factura Partida From Factura
-- Merge
? Select *
Partida From Partida
Partida
Partida
Factura Partida

Partida
Factura Partida
Select *
Partida
From Factura
Partida Partida
Fetch {
Factura Partida Factura Partida
Select *
From Partida
Partida Partida

información confidencial
Otros problemas

Caching de Objetos: Problema de igualdad.


Objetos compartidos
Objetos bloqueados
Transacciones sobre objetos

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);

información confidencial
Patrones de Diseño involucrados
Data Access Object

información confidencial
Domain Store

Administrador
Administrador
Clases de De
De
Negocio Persistencia
Persistencia

Mapeo

BD

información confidencial
QuickStart
Ambiente utilizado para el Curso

Windows XP Professional Edition Service Pack 2


J2SE Development Kit v. 1.5.0_04
Eclipse SDK 3.1.2
MyEclipse IDE v. 4.1.1 GA
JBoss 4.0.3 SP1
PostgreSQL v. 8.1

MyEclipse4.1.1
MyEclipse 4.1.1GA
GA

EclipseSDK
Eclipse SDK3.1.2
3.1.2

J2SEDevelopment
J2SE DevelopmentKit
Kit1.5.0_06
1.5.0_06

WindowsXP
Windows XPProfessional
ProfessionalEdition
EditionSP2
SP2

información confidencial
Descargar

ftp://ssdesa01
usuario: curso
Password: curso

información confidencial
Estructura del Ambiente de Desarrollo

JBoss
JBoss
PostgreSQL
8.1
JavaVirtual
Java VirtualMachine
Machine

Deployment
Plugins DB Explorer
Services

MyEclipse
MyEclipse

Eclipse
Eclipse

JavaVirtual
Java VirtualMachine
Machine

información confidencial
Verificación de Ambiente

JDK
Variable de entorno JAVA_HOME válida
%JAVA_HOME%\bin en el PATH
Ejecutar en línea de comandos java -version

información confidencial
Verificación de Ambiente

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

información confidencial
Verificación de Ambiente

JBoss
Localizar la carpeta donde está instalado (usualmente
C:\Java\jboss-4.0.3SP1)
A esta carpeta le llamaremos de ahora en adelante
JBOSS_HOME
Posicionarse en línea de comandos en:
%JBOSS_HOME%\bin
Y ejecutar el comando: run.bat

información confidencial
Verificando el Ambiente

PostgreSQL

información confidencial
Arrancar la Base de Datos

información confidencial
Crear Base de Datos

información confidencial
Tabla de Prueba

información confidencial
Nuevo Proyecto

información confidencial
Configuración del Proyecto Java

información confidencial
Finalizando la configuración

información confidencial
Configuración de una conexión

información confidencial
Edición del driver

información confidencial
Agregando el Driver

información confidencial
Driver configurado

información confidencial
Configuración de un Profile de Conexión

información confidencial
Finish…

información confidencial
Abriendo la Conexión

información confidencial
Abrir Conexión…

información confidencial
Habilitando Hibernate en nuestro proyecto

información confidencial
Configuración de Hibernate

información confidencial
Creación de la Configuración

información confidencial
Creación de un SessionFactory

información confidencial
Interfases Hibernate

Session
Aplicación Hibernate
Hibernate jdbc
Transaction BD
Java
Query

Cfg
(xml)

información confidencial
Elementos Creados

<<uses>>
Mappings.hbm.xml
<<uses>> Mappings.hbm.xml
SessionFactory Hibernate.cfg.xml Mappings.hbm.xml
currentSession()

<<uses>> Clases
Clases
Session Clases
Persistentes
Persistentes
Clases
Persistentes
Persistentes

Clase
Query
Aplicativa

información confidencial
Configuración de la Conexión en Hibernate

información confidencial
Conexión en Hibernate

información confidencial
Mapping de 1 tabla

información confidencial
ID Generator

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>
<property
name="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> información confidencial


Código Generado

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=info
log4j.logger.org.hibernate=info

### log HQL query parser activity


#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL


log4j.logger.org.hibernate.SQL=info

### log JDBC bind parameters ###


#log4j.logger.org.hibernate.type=debug

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 Creating
SessionFactory %%%%");
e.printStackTrace();
}
}
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}

información confidencial
Prueba

public static void main(String[] args) {


// Step 1 - Create a new entity
Mensajes message = new Mensajes();
// Step 2 - Set message field
message.setTexto("Hello Hibernate, from MyEclipse!");

try {
// Step 3 - Get a Hibernate Session
Session session = HSessionFactory.currentSession();
// Step 4 - Persist entity to database
Transaction 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 session
HSessionFactory.closeSession();
} catch (HibernateException e1) {
// do nothing
}
}
}

información confidencial
2005-11-10 22:40:49,390 [main] INFO org.hibernate.impl.SessionFactoryImpl -
Checking 0 named queries
2005-11-10 22:40:49,468 [main] WARN
org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 42P01
2005-11-10 22:40:49,468 [main] ERROR
org.hibernate.util.JDBCExceptionReporter - ERROR: relation "hibernate_sequence"
does not exist
Save failed.

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 queries
Save successful.

información confidencial
Resultado en la base de datos

información confidencial
Prueba 2

public static void main(String[] args) {


try {
// Step 1 - Get a Hibernate Session
Session session = HSessionFactory.currentSession();
// Step 2 - Crea un query
Query q = session.createQuery("from Mensajes");

String qSQL = q.getQueryString();


System.out.println("Query: " + qSQL);

// Step 3 - Ejecuta el query


List 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) {

información confidencial
Prueba 3

public static void main(String[] args) {


try {
// Step 1 - Get a Hibernate Session
Session session = HSessionFactory.currentSession();
// Step 2 - Crea un query con parametro
Query q = session.createQuery("from Mensajes where id
= :pId");

// Step 3 - Indica el parametro


q.setInteger("pId", 1);

// Step 4 - Ejecuta el query


List 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) {

información confidencial
O/R Mapping
Modos de Operación

Administrado y No Administrado

Session
Aplicación Hibernate
Hibernate Connection
jdbc
Transaction Pool BD
Java
Query

Session Transaction
Manager

Aplicación Hibernate
Hibernate
Transaction
Java
Resource
Query Manager
Datasource
BD

información confidencial
Propiedades útiles en hibernate.cfg.xml

show_sql = true
hibernate.default_schema = ESQUEMAX

información confidencial
Modelo de Pruebas

Producto

Factura Partida

Cliente

información confidencial
Escritura de POJO’s

Deben
Implementar Serializable
Implementar un constructor vacío

información confidencial
Escritura de POJO’s

Declarar los métodos set y get de cada propiedad/columna


excepto la llave primaria.

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.

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.

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;
}

información confidencial
Cliente.hbm.xml

DTD

Paquete

Clase

PK

Asociación

información confidencial
Factura.hbm.xml

FK

información confidencial
Partida.hbm.xml

Llave
Compuesta

Llave foránea
dentro de Llave
Compuesta

información confidencial
Opciones de ID’s

native
identity
sequence
assigned

información confidencial
Consultas
get()

int clienteId=1;

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

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

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();

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’ ”);

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();

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();

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();

información confidencial
Paginación

Utilizando un objeto Query o Criteria

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

información confidencial
Leyendo 1 solo renglón

query.setMaxResult(1);

query.uniqueResult();

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.

información confidencial
Estrategias de Fetching

Immediate Fetching
Inmediato (1 por 1)
Lazy Fetching
En el primer acceso (por default)
Eager Fetching
El objeto y sus relaciones
Batch Fetching
Lectura en lotes (merge)

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”

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.

información confidencial
Eager Fetching

Por default, se usa lazy loading…

Para provocar el eager fetching en tiempo de ejecución


se describe la intención en el query:

from Factura f
left join fetch f.partidaSet

información confidencial
Theta-join

Se utiliza en tablas que no tienen una asociación


definida

from User user, LogRecord log


where 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];
}

información confidencial
Report Queries

Tabular

select item.id, item.description


order 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.

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 f
where 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”.

información confidencial
Persistencia
Ciclo de Vida de un Objeto

información confidencial
Creando un objeto persistente

Cliente cliente = new Cliente();

cliente.setNombre(“Juan”);
cliente.setPaterno(“Perez”);
cliente.setEmail(“x@xxx.org”);

Session session = QSSessionFactory.currentSession();


Transaction tx = session.beginTransaction();

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

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(“xyz@xxx.org”);

tx.commit();
session.close();
Cualquier objeto
asociado a la base
de datos, se
actualiza
automáticamente.

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(“xyz@xxx.org”);

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

información confidencial
Borrado de un Objeto

session.delete(objeto)

información confidencial
Ejercicio

Instale el ambiente de desarrollo


JDK
PostgreSQL
Eclipse
MyEclipse
Cree una base de datos con PGAdminIII
Corra el script creaTestHibernate.sql
Genere el proyecto configurado para Hibernate
Genere los mappings de las tablas recién creadas
Escriba código que
Inserte 2 clientes nuevos
Inserte 2 productos nuevos
Inserte 1 factura a cada cliente con su respectiva partida y
referenciando a 1 producto
Liste los clientes con sus facturas con sus partidas con sus
productos

información confidencial
Transacciones
Manejo de Transacciones

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


siguiente:

información confidencial
Transacciones dentro del Contenedor J2EE

Session Transaction
Manager

Aplicación Hibernate
Hibernate
Transaction
Java
Resource
Query Manager
Datasource
BD

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

información confidencial
JTA Transaction Manager

org.hibernate.transaction.JBossTransactionManagerLookup JBoss
org.hibernate.transaction.WeblogicTransactionManagerLookup Weblogic
org.hibernate.transaction.WebSphereTransactionManagerLookup WebSphere
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup WebSphere 6
org.hibernate.transaction.OrionTransactionManagerLookup Orion/OC4J/OracleAS
org.hibernate.transaction.ResinTransactionManagerLookup Resin
org.hibernate.transaction.JOTMTransactionManagerLookup JOTM
org.hibernate.transaction.JOnASTransactionManagerLookup JOnAS
org.hibernate.transaction.JRun4TransactionManagerLookup JRun4
org.hibernate.transaction.BESTransactionManagerLookup Borland ES

información confidencial
Hibernate Tools
Conversión entre Modelos

UML(XMI)
UML (XMI)

Reverse
AndroMDA
Engineering

POJO’s
POJO’s

Xdoclet hbm2java

O/RMapping
O/R Mapping

hbm2ddl Middlegen

DDL
DDL

información confidencial
Instalación de Hibernate Tools

Simplemente se desempaca el paquete que contiene los


Hiberneta Tools en el directorio de Eclipse.

información confidencial
Nuevo proyecto Java…

información confidencial
Configuración Proyecto Java

información confidencial
Nuevo Java Package

información confidencial
Nuevo Hibernate Configuration File

información confidencial
Create Hibernate Console Configuration

información confidencial
Verificando

información confidencial
Artifact Generation

información confidencial
Configuración de Artifact Generation

información confidencial
Setup Reverse Engineering

información confidencial
Selección de carpeta y nombre

información confidencial
Include… Exclude…

información confidencial
Configuración final

información confidencial
Confirmación…

información confidencial
Artefactos Generados

información confidencial
HQL Editor

información confidencial
Modelo Relacional

información confidencial
Preguntas…

información confidencial
Referencias

Hibernate in Action
Christian Bauer, Gaving King
Manning
(disponible en pdf)

www.hibernate.org
Downloads, documentación de referencia.

http://caveatemptor.hibernate.org
Aplicación demo de hibernate

Sun J2EE Patterns Catalog


http://java.sun.com/blueprints/patterns/catalog.html

información confidencial

También podría gustarte