Sei sulla pagina 1di 24

HIbernate - Parte 1: Persistiendo Objetos Simples usando Mapeos en XML

En la mayora de las aplicaciones empresariales, si no es que en todas, una parte muy importante es
el almacenamiento de datos de forma que estos datos puedan sobrevivir ms all del tiempo que
nuestra aplicacin est encendida (ya sea en una aplicacin standalone o en una aplicacin web).
El almacn de datos ms comn son las bases de datos relacionales. a naturale!a de estas bases
"ace que no sea tan fcil usarlas en el almacenamiento de datos en aplicaciones orientadas a ob#etos
(por las diferencias entre el modelo de datos de objetos y el modelo de datos relacionales), ya que
para $uardar un ob#eto debemos e%traer cada una de sus propiedades que queremos persistir y armar
con ellos una sentencia &'(E)* de (+. ,e la misma forma, cuando queremos recuperar los datos
de un ob#eto, debemos usar una sentencia (EE-* de (+ y despus e%traer el valor de cada una
de las columnas recuperadas y llenar as nuestro ob#eto.
Esto puede no parecer un problema en aplicaciones peque.as, pero cuando comen!amos a tener
muc"os ob#etos que debemos $uardar se vuelve al$o muy pesado y en$orroso, adems de que
consume muc"o de nuestro tiempo que podramos dedicar a me#orar la l$ica de la aplicacin, o a
reali!ar pruebas de la misma.
Esto se "i!o de esta manera durante muc"os a.os, "asta que comen!aron a sur$ir las soluciones de
/apeo 0b#eto1)elacional (0)/ por sus si$las en in$ls). El mapeo ob#eto1relacional se refiere a
una tcnica de mapear representaciones de datos de un modelo de ob#etos a un modelo de datos
relacionales con un esquema basado en (+.
Hibernate, como la definen sus autores, es una "erramienta de mapeo ob#eto1relacional para
ambientes 2ava. 3dems no solo se encar$a del mapeo de clases 2ava a tablas de la base de datos (y
de re$reso), sino que tambin mane#a los queries y recuperacin de datos, lo que puede reducir de
forma si$nificativa el tiempo de desarrollo que de otra forma $astaramos mane#ando los datos de
forma manual con (+ y 2,4-, encar$ndose de esta forma de alrededor del 567 de las tareas
comunes relacionadas con la persistencia de datos, mane#ando todos los problemas relativos con la
base de datos particular con la que estemos traba#ando, de forma transparente para nosotros como
desarrolladores. Entonces, si cambiamos el mane#ador de base de datos no ser necesario que
modifiquemos todo el (+ que ya tenamos para adaptarse al (+ que mane#a la nueva base de
datos. (olo ser necesario modificar una lnea en un arc"ivo de confi$uracin de 8ibernate, y este
se encar$ar del resto.
En esta serie de tutoriales veremos cmo usar 8ibernate para reali!ar las tareas ms comunes
cuando traba#amos con bases de datos. E%isten dos formas de "acer los mapeos en 8ibernate, la
primera es a travs de arc"ivos de mapeo en 9/, que es la forma que veremos en este primer
tutorial. a otra forma es usando anotaciones, que de#aremos para la se$unda. 3s que comencemos.
:ara los tutoriales usaremos /y(+ 6.; como base de datos. *ambin deben ba#ar el conector para
2ava versin 6.;.<.
-reamos una base de datos llamada =prueba"ibernate=. 'o se preocupen por crear al$una tabla, ya
que "aremos que sea el propio 8ibernate el que las $enere. 3"ora comencemos con nuestra
aplicacin.
o primero que "aremos es crear una biblioteca de 'et4eans con los #ars bsicos de 8ibernate, de
esta forma cada ve! que queramos usar 8ibernate en un proyecto solo tendremos que a$re$ar esta
biblioteca. En realidad no crearemos esta biblioteca desde cero, ya que 'et4eans ya tiene una
biblioteca de 8ibernate >.?.6, solo actuali!aremos la biblioteca con la ltima versin de 8ibernate,
la >.>.; @3. 3s que descar$amos la ltima versin del core de 8ibernate desde la p$ina de
descar$a de 8ibernate.
Ana ve! que descar$uemos y descomprimamos el arc"ivo correspondiente veremos que en la ra!
"ay dos #ars de 8ibernateB ="ibernate>.#ar= y ="ibernateCtestin$.#ar=. ="ibernate>.#ar= contiene las
clases principales para el uso de 8ibernate. E%isten varias clases de soporte que son usadas por
8ibernate para su funcionamiento normal. 3l$unas son opcionales y otras son requeridas.
3fortunadamente estas se encuentran separadas en el mismo arc"ivo que "emos descar$ado. as
clases obli$atorias, que son las que nos interesan en este caso, se encuentran en el directorio
=libDrequired=.
4ien, entonces para actuali!ar la biblioteca abrimos el 'et4eans y nos diri$imos al men =*ools CE
ibraries=B
En la ventana que se abre buscamos la biblioteca =8ibernate= y la seleccionamos. -on esto se
mostrarn los arc"ivos que la conforman. (eleccionamos todos los arc"ivos y presionamos el botn
=)emove= para eliminarlos de la biblioteca.
Ana ve! eliminados los arc"ivos presionamos el botn =3dd 23)1Folder...= para a$re$ar los nuevos
arc"ivosB
3$re$amos a la biblioteca los si$uientes arc"ivosB
"ibernate>.#ar
y del directorio de #ars requeridosB
antlrC?.<.G.#ar
commonsCcollectionsC>.;.#ar
domH#C;.G.;.#ar
#avassistC>.H.@3.#ar
#taC;.;.#ar
0 sea, casi todos los arc"ivos requeridos. Estamos e%cluyendo el arc"ivo =slfH#CapiC;.6.?.#ar=
porque si lo incluimos solo, se lan!a una e%cepcin. o que ocurre es que slfH# es una fac"ada para
el lo$$in$, o bitcora de la aplicacin (similar a =commonsClo$$in$= que estuvimos usando el los
tutoriales de 2asper)eports). Esto si$nifica que podemos usar el frameworI de lo$$in$ que
queramos (en teora). (in embar$o en la distribucin de 8ibernate no se incluye nin$n #ar con una
clase que implemente dic"a fachada, por lo que debemos ba#ar uno nosotros mismos.
:odemos "acer dos cosas, la primer es a$re$ar el arc"ivo =slfH#CapiC;.6.?.#ar= que viene con
8ibernate a nuestra biblioteca y el !ip con la versin correspontiente de slfH#. ,e l e%traemos
=slfH#CsimpleC;.6.?.#ar= (o el arc"ivo que se a#uste al frameworI de lo$$in$ que estemos usando) y
lo incluimos en la biblioteca.
o otro que podemos "acer es, aprovec"ando que ya estamos ba#ando #ars, descar$ar la ltima
versin de slfH# de aqu (actualmente es la ;.6.G) y aprovec"ar para a$re$ar los arc"ivos =slfH#CapiC
;.6.G.#ar= y =slfH#CsimpleC;.6.G.#ar= a nuestra biblioteca. Jo "ar esto ltimo.
Ana ve! seleccionados estos arc"ivos la biblioteca de 8ibernate debe verse asB
:resionamos el botn =0K= y nuestra biblioteca ya estar actuali!ada.
3"ora creamos un nuevo proyecto de 'et4eans (men =File CE 'ew :ro#ect... CE 2ava CE 2ava
3pplication=). e damos un nombre y una ubicacin al proyecto y nos ase$uramos de que las
opciones =-reate /ain -lass= y =(et as /ain :ro#ect= estn "abilitadas. :resionamos el botn
=Finis"= y veremos aparecer en el editor nuestra clase =/ain=.
3$re$amos la biblioteca de =8ibernate=, que creamos "ace unos momentos, a nuestro proyecto.
8acemos clic derec"o en el nodo =ibraries= del proyecto. En el men conte%tual que se abre
seleccionamos la opcin =3dd ibrary...=B
En la ventana que se abre seleccionamos la biblioteca =8ibernate=B
:resionamos el botn =3dd ibrary= para que la biblioteca se a$re$ue a nuestro proyecto.
3provec"amos tambin para a$re$ar el conector de /y(+. ,ebemos tener los si$uientes arc"ivos
en nuestro proyectoB
El si$uiente paso es crear una clase cuyas instancias sern almacenadas como fila de una tabla en
base de datos. Este tipo de ob#etos son llamados =Entidades=. :ara este e#emplo crearemos una
peque.a y bsica a$enda, as que las entidades sern ob#etos de la clase =-ontacto=.
os atributos que tendr esta sern un nombre, un correo, y un nmero telefnico. 3dems, por
re$la, necesitamos un atributo que funcione como identificador para cada una de las entidades.
En este caso "e "ec"o que la clase implementa la interface =java.io.(eriali!able=, esto no es
obli$atorio pero es una buena prctica.
a clase =-ontacto= queda de la si$uiente formaB
public class Contacto implements Serializable
{
private long id;
private String nombre;
private String email;
private String telefono;
public Contacto()
{
}
public Contacto(String nombre, String email, String telefono)
{
this.nombre = nombre;
this.email = email;
this.telefono = telefono;
}
public String getmail()
{
return email;
}
public void setmail(String email)
{
this.email = email;
}
public long get!d()
{
return id;
}
private void set!d(long id)
{
this.id = id;
}
public String get"ombre()
{
return nombre;
}
public void set"ombre(String nombre)
{
this.nombre = nombre;
}
public String get#elefono()
{
return telefono;
}
public void set#elefono(String telefono)
{
this.telefono = telefono;
}
}
a clase =-ontacto= usa la convencin de nombres 2ava4eans para los $etters y setters y visibilidad
privada para los atributos. Este tambin es un dise.o recomendado pero no obli$atorio. 8ibernate
puede acceder a los campos o atributos de las entidades directamente.
El constructor sin ar$umentos si es obli$atorio ya que 8ibernate crear instancias de esta clase
usando refle%in cuando recupere las entidades de la base de datos. Este constructor puede ser
privado (si es que no quieren permitir que al$uien ms lo utilice), pero usualmente el nivel de
acceso ms restrictivo que usaremos es el de paquete (el default), ya que esto "ace ms eficiente la
creacin de los ob#etos.
a propiedad =id= mantendr, como di#e antes, un valor nico que identificar a cada una de las
instancias de =-ontacto=. *odas las clases de entidades persistentes deben tener una propiedad que
sirva como identificador si queremos usar el con#unto completo de funcionalidades que nos ofrece
8ibernate (y que veremos a lo lar$o de esta serie de tutoriales). ,e todas formas, la mayora de las
aplicaciones necesitan poder distin$uir ob#etos de la misma clase mediante al$n tipo de
identificador. Asualmente no manipulamos directamente este identificador (de#amos que sea la base
de datos quien lo $enere, cuando la entidad sea $uardada, y 8ibernate quien lo asi$ne al ob#eto), por
lo tanto el setter del =id= es privado (f#ense cmo lo "e puesto en la clase =-ontacto=).
8ibernate puede acceder a los campos private directamente, as que no debemos preocuparnos por
el "ec"o de que el identificador no pudiera ser establecido.
El si$uiente paso es crear el arc"ivo de mapeo. (i recuerdan, anteriormente di#e que 8ibernate es
una "erramienta de mapeos 0b#eto1)elacional, o sea que mapea los atributos de los ob#etos con las
columnas de una tabla de una base de datos relacional. *ambin di#e que "ay dos formas de "acerloB
mediante un arc"ivo de mapeo en 9/ y mediante anotaciones y que en esta ocasin veramos solo
como usar los arc"ivos de mapeo.
-rearemos un nuevo paquete que contendr los arc"ivos de mapeo, no es obli$atorio tener los
arc"ivos de mapeo en un paquete separado ya que ms adelante indicaremos donde se encuentra
cada uno de los arc"ivos, pero nos ayudar a mantener un poco de orden en nuestro proyecto.
8acemos clic derec"o sobre el nodo =(ource :acIa$es= del proyecto para mostrar un men
conte%tual. ,e ese men seleccionamos la opcin ='ew CE 2ava :acIa$e..=B
'ombramos a este paquete como =mapeos= y presionamos el botn =Finis"= para a$re$ar el nuevo
paquete.
3"ora creamos un nuevo arc"ivo 9/ que contendr el mapeo de la clase =-ontacto= con la tabla
=-0'*3-*0(= de la base de datos. :or convencin la e%tensin de estos arc"ivos es =."bm.%ml= y
tiene el mismo nombre de la entidad que est mapeando (aunque eso tampoco es necesario ya que
podemos mapear ms de una clase o entidad dentro del mismo arc"ivo).
8acemos clic derec"o sobre el paquete que acabamos de crear. En el men conte%tual que se abre
seleccionamos la opcin ='ew CE 9/ ,ocument=. (i no se muestra est opcin seleccionamos
=0t"er...= y en la ventana que se abre seleccionamos =9/ CE 9/ ,ocument=B
e damos al arc"ivo el nombre =-ontacto."bm= (el asistente se encar$ar de a$re$ar de forma
automtica el =.%ml= al final)B
:resionamos el botn ='e%t E= y se nos pre$untar qu tipo de documento queremos crearB solo un
documento 9/ bien formado, un documento re$ido por un ,*,, o un documento re$ido por un
(c"ema 9/. 3unque el documento de mapeo est re$ido por un ,*, nosotros ele$iremos crear
un documento 9/ bien formado (=LellCformed ,ocument=) ya que es ms fcil simplemente
pe$arlo en el arc"ivo que se crear que indicar mediante el asistente dnde se encuentra este
arc"ivo. :resionamos el botn =Finis"= para que se nos muestre en el editor el nuevo arc"ivo 9/,
el cual debe verse ms o menos asB
/odificaremos este arc"ivo. Eliminamos todo el contenido del arc"ivo y lo reempla!amos por esteB
$%&ml version='(.)'%*
$+,-C#./ hibernate0mapping /123!C
'0445ibernate45ibernate 6apping ,#, 7.)44"'
'http844hibernate.sourceforge.net4hibernate0mapping07.).dtd'*
$hibernate0mapping*

$4hibernate0mapping*
*eniendo esta declaracin, la cual indica el ,*, que se usa para validar el arc"ivo, el &,E nos
ayudar a autocompletar las etiquetas y a ase$urarnos que el arc"ivo sea vlido.
El elemento =M"ibernateCmappin$E= es el nodo ra! del documento y, por lo tanto, el resto de los
elementos irn entre estas dos etiquetas.
El elemento con el que indicamos qu clase es la que estamos mapeando es el elemento =MclassE=
este elemento tiene los atributos =name= y =table= que nos permiten indicar el nombre completo de
la clase y la tabla con la que ser mapeada, respectivamenteB
$hibernate0mapping*
$class name='hibernatenormal.Contacto' table='C-"#9C#-S'*
$4class*
$4hibernate0mapping*
-on esto indicamos que las entidades de la clase =-ontacto= sern almacenadas en la tabla
=-0'*3-*0(=. 3"ora debemos indicar cul de los elementos de la clase entidad es el
identificador. Este identificador ser mapeado con la llave primaria de la tabla, adems como
nosotros no mane#aremos el valor del identificador, le indicamos a 8ibernate cmo queremos que
este valor sea $enerado (la estrate$ia de $eneracin). :ara esto usamos el elemento =MidE=,
indicando el nombre del atributo de la clase entidad que representa el identificador (que en este caso
tambin se llama =id= NCN). 0pcionalmente en este elemento (como en el resto de los elementos de
mapeo de propiedades) podemos indicar con qu columna queremos que se mapee usando el
atributo =column=B
$hibernate0mapping*
$class name='hibernatenormal.Contacto' table='C-"#9C#-S'*
$id name='id' column='!,'*
$generator class='identit:' 4*
$4id*
$4class*
$4hibernate0mapping*
El elemento =M$eneratorE= es el que nos permite indicar la estrate$ia de $eneracin del
identificador usando su atributo =class=. E%isten varias estrate$ias que estn e%plicadas en esta
p$ina, pero las que usaremos ms frecuentemente son =identity= (con la que 8ibernate se encar$a
de $enerar el query necesario para que el nuevo identificador sea i$ual a el ltimo identificador O ;)
y =native= (con el que se usa la estrate$ia por default del mane#ador que estemos utili!ando
(dialecto)).
:ara terminar con el mapeo incluimos las declaraciones para el resto de las propiedades persistentes
(las que queremos que sean almacenadas) de la clase entidad (=nombre=, =email=, y =telefono=)
usando el elemento =MpropertyE= en el cual indicamos el nombre de la propiedad como aparece en
la clase entidad y, opcionalmente, el tipo de la propiedad y la columna con la que ser mapeada
usando los atributos =type= y =column= respectivamenteB
$hibernate0mapping*
$class name='hibernatenormal.Contacto' table='C-"#9C#-S'*
$id name='id' column='!,'*
$generator class='identit:' 4*
$4id*
$propert: name='nombre' t:pe='string' column='"-62;' 4*
$propert: name='email' 4*
$propert: name='telefono' 4*
$4class*
$4hibernate0mapping*
El arc"ivo =-ontacto."bm.%ml= final debe verse asB
P+u ocurre si no indicamos el tipo de la propiedadQ En ese caso 8ibernate utili!a nuevamente
reflein en nuestra clase para determinar el tipo del atributo y as ele$ir el tipo ms adecuado para
la columna de la tabla (en caso de que de#emos que 8ibernate $enere las tablas).
P+u ocurre si no indicamos el nombre de la columna con la que mapea una propiedadQ Esto
depende de si 8ibernate est $enerando las tablas de la base de datos o las "emos $enerado nosotros
mismos. (i es 8ibernate quien est $enerando las tablas no "ay problema, simplemente dar a la
columna correspondiente el mismos nombre de la propiedad. :or e#emplo, para la propiedad
=email= crear una columna =email=. (in embar$o, si nosotros "emos creado las tablas "ay un ries$o
potencial de un error. 8ibernate buscar en las consultas una columna con el mismo nombre de la
propiedad, pero si "emos usado un nombre distinto, por e#emplo en ve! de =email= "emos llamado a
la columna =ER/3&= ocurrir una e%cepcin indicando que no se "a encontrado la columna
=email=, as que en ese caso debemos tener cuidado de indicar el nombre de las columnas como
estn en la base de datos.
4ien, despus de esta breve e%plicacin podemos prose$uir.
Ja que "emos confi$urado el mapeo de nuestra clase entidad debemos confi$urar 8ibernate.
8ibernate est en la capa de nuestra aplicacin que se conecta a la base de datos (la capa de
persistencia), as que necesita informacin de la cone%in. a cone%in se "ace a travs de un pool
de cone%iones 2,4- que tambin debemos confi$urar. a distribucin de 8ibernate contiene
muc"os pools de cone%iones 2,4- 0pen (ource, como por e#emplo ->:S, pero en esta ocasin
usaremos el pool de coneiones que 8ibernate trae inte$rado.
a confi$uracin de 8ibernate puede "acerse en tres lu$aresB
An arc"ivo de propiedades llamado ="ibernate.properties=.
An arc"ivo 9/ llamado ="ibernate.cf$.%ml=.
En cdi$o dentro de la misma aplicacin.
En realidad los arc"ivos pueden tener cualquier nombre, pero 8ibernate buscar por default los
arc"ivos con los nombres que "e mencionado, en una ubicacin predeterminada (la ra! del
classpat" de la aplicacin). (i queremos usar arc"ivos con otros nombres deberemos especificarlo
en el cdi$o.
a mayora, por lo que "e podido ver en &nternet, preferimos usar el arc"ivo 9/ ya que, entre
otras cosas, los &,Es nos ayudan a su creacin y confi$uracin $racias a que est re$ido por un
,*,. 3s que crearemos este arc"ivo en nuestro proyecto. 8acemos clic derec"o en el nodo
=(ource :acIa$es= del proyecto. En el men conte%tual que se abre seleccionamos ='ew CE 9/
,ocument...=B
'ombramos al arc"ivo ="ibernate.cf$=, el &,E se encar$ar de colocarle la e%tensin =.%ml=.
Abicamos el arc"ivo en el directorio =src=B
-on esto lo$raremos que el arc"ivo quede en la ra! del classpat" de la aplicacin, tambin
conocido como el paquete default. :resionamos el botn ='e%t E= y en la pantalla si$uiente
indicamos que queremos crear un documento 9/ bien formado (como en el caso anterior).
:resionamos el botn =Finis" = para $enerar el arc"ivo. (i nos fi#amos en el arc"ivo $enerado, este
debe encontrarse en un paquete llamado =Mdefault pacIa$eE=B
4orramos todo el contenido del arc"ivo $enerado y colocamos las si$uientes lneasB
$%&ml version=<(.)< encoding=<utf0=<%*
$+,-C#./ hibernate0configuration /123!C
'0445ibernate45ibernate Configuration ,#, 7.)44"'
'http844hibernate.sourceforge.net4hibernate0configuration07.).dtd'*
$hibernate0configuration*
$4hibernate0configuration*
El ,*, nos ayudar para que el &,E autocomplete las etiquetas.
-omo podemos ver, el elemento ra! del arc"ivo de confi$uracin es =M"ibernateCconfi$urationE= y,
por lo tanto, todos los elementos los colocaremos entre estas dos etiquetas.
o primero que debemos "acer es confi$urar un =sessionCfactory=, que bsicamente es lo que le dice
a 8ibernate cmo conectarse y mane#ar la cone%in a la base de datos. :odemos tener ms de un
=sessionCfactory= en el arc"ivo de confi$uracin (por si quisiramos conectarnos a ms de una base
de datos), pero por lo re$ular solo ponemos unoB
$hibernate0configuration*
$session0factor:*

$4session0factor:*
$4hibernate0configuration*
o si$uiente es confi$urar la cone%in a nuestra base de datos. En este arc"ivo se confi$uran los
parmetros bsicos y tpicos para una cone%in (la A), nombre de usuario, contrase.a, driver,
etc.). -ada uno de estos parmetros se confi$ura dentro de una etiqueta =MpropertyE= (al i$ual que
casi todos los elementos del arc"ivo de confi$uracin). -omo di#e antes, usar una base de datos
/y(+ para este e#emplo, as que mi confi$uracin queda de la si$uiente formaB
$propert: name='connection.driver>class'*com.m:s?l.@dbc.,river$4propert:*
$propert:
name='connection.url'*@dbc8m:s?l844localhost4pruebahibernate$4propert:*
$propert: name='connection.username'*usuario$4propert:*
$propert: name='connection.passAord'*passAord$4propert:*
,espus, confi$uramos el pool de cone%iones de 8ibernate. En este caso como es un e#emplo muy
simple, solo nos interesa tener una cone%in en el pool, por lo que colocamos la propiedad
=connection.poolRsi!e= con un valor de =;=B
$propert: name='connection.pool>size'*($4propert:*
El si$uiente paso es muy importante. ,ebemos indicar el =dialecto= que usar 8ibernate para
comunicarse con la base de datos. Este dialecto es la variante de (+ que usa la base de datos para
e#ecutar queries. &ndicamos el dialecto con el fully qualified class name, o el nombre completo de la
clase incluyendo el paquete. En el caso de /y(+ 6 usamos
=or$."ibernate.dialect./y(+6,ialect=. En esta p$ina pueden encontrar una lista ms o menos
completa de los dialectos soportados por 8ibernate, pero siempre es me#or revisar la documentacin
de la versin que estn usando para estar se$urosB
$propert: name='dialect'*org.hibernate.dialect.6:SB3C,ialect$4propert:*
0tras dos propiedades importantes que podemos confi$urar sonB =s"owRsql= que indica si queremos
que las consultas (+ $eneradas sean mostradas en el stdout (normalmente la consola), y
="bm?ddl.auto=, que indica si queremos que se $enere automticamente el esquema de la base de
datos (las tablas). =s"owRsql= puede tomar valores de =true= o =false=, yo lo colocar en =true= (lo
que puede ser bueno mientras estamos en etapas de desarrollo o pruebas, pero querrn cambiar su
valor cuando su aplicacin pase a produccin). :or otro lado ="bm?ddl.auto= puede tomar los
valores, se$un la documentacin oficial(falta =none=), de =validate=, =update=, =create=, y =createC
drop= (aunque no todos los valores funcionan para todas las bases de datos). Jo los colocar de la
si$uiente formaB
$propert: name='shoA>s?l'*true$4propert:*
$propert: name='hbmDddl.auto'*create0drop$4propert:*
-on el valor =createCdrop= "acemos que cada ve! que se e#ecute la aplicacin 8ibernate elimine las
tablas de la base de datos y las vuelva a crear. :ara terminar con este arc"ivo de confi$uracin,
debemos indicar dnde se encuentra cada uno de los arc"ivos de mapeo que "emos creado, usando
el elemento =Mmappin$E=. En nuestro caso solo "emos creado un arc"ivo de mapeo, pero debemos
colocar un elemento =Mmappin$E= por cada uno de los arc"ivos que "ayamos creadoB
$mapping resource='mapeos4Contacto.hbm.&ml'4*
En el elemento =resource= debemos colocar la ubicacin de los arc"ivos de mapeo dentro de la
estructura de paquetes de la aplicacin. El arc"ivo de confi$uracin ="ibernate.cf$.%ml= final debe
verse asB
$%&ml version='(.)' encoding='1#E0='%*
$+,-C#./ hibernate0configuration /123!C
'0445ibernate45ibernate Configuration ,#, 7.)44"'
'http844hibernate.sourceforge.net4hibernate0configuration07.).dtd'*
$hibernate0configuration*
$session0factor:*

$+00 parametros para la cone&ion a la base de datos 00*
$propert: name='connection.driver>class'*com.m:s?l.@dbc.,river$4propert:*
$propert:
name='connection.url'*@dbc8m:s?l844localhost4pruebahibernate$4propert:*
$propert: name='connection.username'*usuario$4propert:*
$propert: name='connection.passAord'*passAord$4propert:*

$+00 Configuracion del pool interno 00*
$propert: name='connection.pool>size'*($4propert:*

$+00 ,ialecto de la base de datos 00*
$propert: name='dialect'*org.hibernate.dialect.6:SB3C,ialect$4propert:*

$+00 -tras propiedades importantes 00*
$propert: name='shoA>s?l'*true$4propert:*
$propert: name='hbmDddl.auto'*create0drop$4propert:*

$+00 9rchivos de mapeo 00*
$mapping resource='mapeos4Contacto.hbm.&ml'4*
$4session0factor:*
$4hibernate0configuration*
Esta es toda la confi$uracin que debemos "acer. 3"ora veremos el cdi$o necesario para $uardar y
recuperar ob#etos =-ontacto= de la base de datos.
o primero que "aremos es crear una clase ayudante o de utilidad llamada =8ibernateAtil=, que se
"ar car$o de iniciali!ar y "acer el acceso al =or$."ibernate.(essionFactory= (el ob#eto encar$ado de
$estionar las sesiones de cone%in a la base de datos que confi$uramos en el arc"ivo
="ibernate.cf$.%ml=) ms conveniente.
,entro de esta clase declaramos un atributo static de tipo =(essionFactory=, as nos ase$uraremos
de que solo e%iste una instancia en la aplicacin. 3dems lo declararemos como final para que la
referencia no pueda ser cambiada despus de que la "ayamos asi$nado.
private static final SessionEactor: sessionEactor:;
,espus usamos un bloque de iniciali!acin esttico para iniciali!ar esta variable en el momento en
el que la clase sea car$ada en la 2T/.
:ara reali!ar esta iniciali!acin lo primero que se necesita es una instancia de la clase
=or$."ibernate.cf$.-onfi$uration= que permite a la aplicacin especificar las propiedades y
documentos de mapeo que se usarn (es aqu donde indicamos todo si no queremos usar un arc"ivo
9/ o de propiedades). (i usamos el mtodo =confi$ure()= que no recibe parmetros entonces
8ibernate busca el arc"ivo ="ibernate.cf$.%ml= que creamos anteriormente. Ana ve! que tenemos
este ob#eto, entonces podemos iniciali!ar la instancia de =(essionFactory= con su mtodo
=build(essionFactory()=. 3dems como este proceso puede lan!ar
=or$."ibernate.8ibernateE%ception= (que e%tiende de =)untimeE%ception=) la cac"amos y lan!amos
como un =E%ception&n&nitiali!arError= (que es lo nico que puede lan!arse desde un bloque de
iniciali!acin). El bloque de iniciali!acin queda de la si$uiente formaB
static
{
tr:
{
sessionEactor: = neA Configuration().configure().buildSessionEactor:();
} catch (5ibernate&ception he)
{
S:stem.err.println('-curriF un error en la inicializaciFn de la
SessionEactor:8 ' G he);
throA neA &ception!n!nitializerrror(he);
}
}
Finalmente creamos un mtodo static llamado =$et(essionFactory()= para recuperar la instancia de
la =(essionFactory=B
public static SessionEactor: getSessionEactor:()
{
return sessionEactor:;
}
a clase =8ibernateAtil= queda de la si$uiente formaB
import org.hibernate.5ibernate&ception;
import org.hibernate.SessionEactor:;
import org.hibernate.cfg.Configuration;
public class 5ibernate1til
{
private static final SessionEactor: sessionEactor:;
static
{
tr:
{
sessionEactor: = neA
Configuration().configure().buildSessionEactor:();
} catch (5ibernate&ception he)
{
S:stem.err.println('-curriF un error en la inicializaciFn de la
SessionEactor:8 ' G he);
throA neA &ception!n!nitializerrror(he);
}
}
public static SessionEactor: getSessionEactor:()
{
return sessionEactor:;
}
}
4ien "a lle$ado el momento, a"ora escribiremos una clase ,30 (no se$uiremos el patrn al pie de
la letra, es solo para mostrar cmo traba#ar con 8ibernate) que nos permitir reali!ar operaciones de
base de datos.
-reamos una clase llamada =-ontactos,30= y a$re$amos dos atributos, uno llamado =sesion= de
tipo =or$."ibernate.(ession=, y otro llamado =t%= de tipo =or$."ibernate.*ransaction=.
private Session sesion;
private #ransaction t&;
Estos atributos nos servirn para mantener la referencia a la sesin a base de datos, y a la
transaccin actual, respectivamente. 3"ora a$re$aremos dos mtodos de utilidad. El primero nos
ayudar a iniciar una sesin y una transaccin en la base de datos. lamaremos a este mtodo
=inicia0peracion=, y la implementacin es la si$uienteB
private void inicia-peracion() throAs 5ibernate&ception
{
sesion = 5ibernate1til.getSessionEactor:().openSession();
t& = sesion.begin#ransaction();
}
En el mtodo anterior obtenemos una referencia a =(essionFactory= usando nuestra clase de utilidad
=8ibernateAtil=. Ana ve! que tenemos la =(essionFactory= creamos una cone%in a la base de datos
e iniciamos una nueva sesin con el mtodo =open(ession()=. Ana ve! teniendo la sesin iniciamos
una nueva transaccin y obtenemos una referencia a ella con =be$in*ransaction()=.
3"ora el se$undo mtodo de utilidad (llamado =mane#aE%cepcion=) nos ayudar a mane#ar las cosas
en caso de que ocurra una e%cepcin. (i esto pasa queremos que la transaccin que estamos
e#ecutando se des"a$a y se relance la e%cepcin (o podramos lan!ar una propia). :or lo que el
mtodo queda asB
private void mane@a&cepcion(5ibernate&ception he) throAs 5ibernate&ception
{
t&.rollbacH();
throA neA 5ibernate&ception('-curriF un error en la capa de acceso a
datos', he);
}
3"ora crearemos los mtodos que nos permitirn reali!ar las tareas de persistencia de una entidad
=-ontacto=, conocidas en len$ua#e de base de datos como -)A,B $uardarla, actuali!arla,
eliminarla, buscar un entidad =-ontacto= y obtener todas los contactos que e%isten en la base de
datos, as que comencemos.
3fortunadamente 8ibernate "ace que esto sea fcil ya que proporciona mtodos para cada una de
estas tareas. :rimero veamos como $uardar un ob#eto =-ontacto=. :ara esto 8ibernate proporciona
el mtodo =save= en el ob#eto de tipo =or$."ibernate.(ession=, que se encar$a de $enerar el
=&'(E)*= apropiado para la entidad que estamos tratando de $uardar. El mtodo =$uarda-ontacto=
queda de la si$uiente formaB
public long guardaContacto(Contacto contacto)
{
long id = );
tr:
{
inicia-peracion();
id = (3ong)sesion.save(contacto);
t&.commit();
}catch(5ibernate&ception he)
{
mane@a&cepcion(he);
throA he;
}finall:
{
sesion.close();
}
return id;
}
)e$resamos el =id= $enerado al $uardar el =-ontacto= solo por si queremos usarlo ms adelante en
el proceso (como lo "aremos nosotros), o si queremos mostrarle al usuario, por al$una ra!n, el
identificador del =-ontacto=.
3"ora veremos cmo actuali!ar un =-ontacto=. :ara eso usamos el mtodo =update= del ob#eto
=sesion= en nuestro mtodo =actuali!a-ontacto=B
public void actualizaContacto(Contacto contacto) throAs 5ibernate&ception
{
tr:
{
inicia-peracion();
sesion.update(contacto);
t&.commit();
}catch (5ibernate&ception he)
{
mane@a&cepcion(he);
throA he;
}finall:
{
sesion.close();
}
}
-omo podemos ver, el mtodo para actuali!ar es muy similar al mtodo para $uardar la entidad. o
mismo ocurre con el mtodo para eliminarla, =elimina-ontacto=B
public void eliminaContacto(Contacto contacto) throAs 5ibernate&ception
{
tr:
{
inicia-peracion();
sesion.delete(contacto);
t&.commit();
} catch (5ibernate&ception he)
{
mane@a&cepcion(he);
throA he;
}finall:
{
sesion.close();
}
}
3"ora veremos unos mtodos un poco ms interesantes.
-uando queremos buscar una entidad podemos usar varios criterios. a forma ms fcil es buscar
una entidad particular usando su =id=. a clase =or$."ibernate.(ession= proporciona dos mtodos
para estoB =load= y =$et=. os dos "acen prcticamente lo mismoB en base al identificador y tipo de
la entidad recuperan la entidad indicada, con la diferencia de que =load= lan!a una e%cepcin en
caso de que la entidad indicada no sea encontrada en la base de datos, mientras que =$et=
simplemente re$resa =null=. :ueden usar el que prefieran, en lo personal me $usta ms =$et=, as que
lo usar para el mtodo =obten-ontacto=B
public Contacto obtenContacto(long idContacto) throAs 5ibernate&ception
{
Contacto contacto = null;
tr:
{
inicia-peracion();
contacto = (Contacto) sesion.get(Contacto.class, idContacto);
} finall:
{
sesion.close();
}
return contacto;
}
Finalmente veremos el mtodo =obtenista-ontactos= que recupera todos los -ontactos que estn
$uardados en la base de datos. -omo en este caso re$resaremos una lista de elementos deberemos
crear una consulta. -uando tenemos que crear una consulta con 2,4- lo "acemos en (+, sin
embar$o con 8ibernate tenemos varias opcionesB
Asar una query en (+ nativo.
-rear una query en 8+ (8ibernate +uery an$ua$e).
-rear una query usando -riteria que es un 3:& para crear queries de una forma ms
=orientada a ob#etos=.
-ritera es, a mi parecer, la forma ms fcil de crear las queries. (in embar$o, tambin en mi
opinin, 8+ es ms poderosa y tenemos ms control sobre lo que est ocurriendo, as que ser esta
forma la que usaremos.
-reando la consulta en 8+ 8ibernate la transformar al (+ apropiado para la base de datos que
estemos usando. a consulta en realidad es muy simpleB indicamos que queremos obtener datos
($enerar un =(EE-*=), en este caso la clausula =(EE-*= no es necesaria (aunque si e%iste)
porque vamos a re$resar todos los datos del ob#eto (podemos indicar solo unos cuantos atributos,
eso es llamado proyeccin, pero se mane#a de una forma distinta). o que si debemos indicar es de
cul clase queremos recuperar las instancias, por lo que necesitamos la clausula =F)0/= y el
nombre de la clase (recuerden que en base al nombre de la clase 8ibernate sabr en cul tabla estn
almacenadas las entidades). Espero que esta e%plicacin se "aya entendido, se que es un poco
enredado, pero quedar ms claro con el e#emploB
public 3ist$Contacto* obten3istaContactos() throAs 5ibernate&ception
{
3ist$Contacto* listaContactos = null;

tr:
{
inicia-peracion();
listaContactos = sesion.createBuer:('from Contacto').list();
}finall:
{
sesion.close();
}
return listaContactos;
}
Eso es todo, nuestra consulta para recuperar todos los -ontactos que tenemos en la base de datos
solo debemos usar la clausula =F)0/ -ontacto=. (i quieren una referencia ms amplia de 8+
pueden encontrarla en el tutorial sobre 8+.
4ien, eso es todo. a clase =-ontactos,30= queda de la si$uiente forma (omitiendo los imports)B
public class Contactos,9-
{
private Session sesion;
private #ransaction t&;
public long guardaContacto(Contacto contacto) throAs 5ibernate&ception
{
long id = );
tr:
{
inicia-peracion();
id = (3ong) sesion.save(contacto);
t&.commit();
} catch (5ibernate&ception he)
{
mane@a&cepcion(he);
throA he;
} finall:
{
sesion.close();
}
return id;
}
public void actualizaContacto(Contacto contacto) throAs 5ibernate&ception
{
tr:
{
inicia-peracion();
sesion.update(contacto);
t&.commit();
} catch (5ibernate&ception he)
{
mane@a&cepcion(he);
throA he;
} finall:
{
sesion.close();
}
}
public void eliminaContacto(Contacto contacto) throAs 5ibernate&ception
{
tr:
{
inicia-peracion();
sesion.delete(contacto);
t&.commit();
} catch (5ibernate&ception he)
{
mane@a&cepcion(he);
throA he;
} finall:
{
sesion.close();
}
}
public Contacto obtenContacto(long idContacto) throAs 5ibernate&ception
{
Contacto contacto = null;
tr:
{
inicia-peracion();
contacto = (Contacto) sesion.get(Contacto.class, idContacto);
} finall:
{
sesion.close();
}
return contacto;
}
public 3ist$Contacto* obten3istaContactos() throAs 5ibernate&ception
{
3ist$Contacto* listaContactos = null;
tr:
{
inicia-peracion();
listaContactos = sesion.createBuer:('from Contacto').list();
} finall:
{
sesion.close();
}
return listaContactos;
}
private void inicia-peracion() throAs 5ibernate&ception
{
sesion = 5ibernate1til.getSessionEactor:().openSession();
t& = sesion.begin#ransaction();
}
private void mane@a&cepcion(5ibernate&ception he) throAs
5ibernate&ception
{
t&.rollbacH();
throA neA 5ibernate&ception('-curriF un error en la capa de acceso a
datos', he);
}
}
3"ora, y para terminar el e#emplo, "aremos uso de =-ontactos,30= para crear y recuperar al$unas
instancias de =-ontacto=. -reo que el cdi$o es muy claro as que no lo e%plicar NCNU. a clase
=/ain= queda de la si$uiente formaB
public class 6ain
{
public static void main(StringIJ args)
{
Contactos,9- contactos,9- = neA Contactos,9-();
Contacto contacto;ecuperado = null;
long id9liminar = );
44Creamos tes instancias de Contacto
Contacto contacto( = neA Contacto('Contacto (',
'contacto(Kcontacto.com', '(D7LCMN=');
Contacto contactoD = neA Contacto('Contacto D',
'contactoDKcontacto.com', '=NMCL7D(');
Contacto contacto7 = neA Contacto('Contacto 7',
'contacto7Kcontacto.com', 'LCM(D7N=');
44Ouardamos las tres instancias, guardamos el id del contacto( para
usarlo posteriormente
id9liminar = contactos,9-.guardaContacto(contacto();
contactos,9-.guardaContacto(contactoD);
contactos,9-.guardaContacto(contacto7);
446odificamos el contacto D : lo actualizamos
contactoD.set"ombre('"uevo Contacto D');
contactos,9-.actualizaContacto(contactoD);
44;ecuperamos el contacto( de la base de datos
contacto;ecuperado = contactos,9-.obtenContacto(id9liminar);
S:stem.out.println(';ecuperamos a ' G contacto;ecuperado.get"ombre());
44liminamos al contacto;ecuperado (?ue es el contacto7)
contactos,9-.eliminaContacto(contacto;ecuperado);
44-btenemos la lista de contactos ?ue ?uedan en la base de datos : la
mostramos
3ist$Contacto* listaContactos = contactos,9-.obten3istaContactos();
S:stem.out.println('5a: ' G listaContactos.size() G 'contactos en la
base de datos');
for(Contacto c 8 listaContactos)
{
S:stem.out.println('0* ' G c.get"ombre());
}
}
}
En el momento que e#ecutemos la aplicacin 8ibernate crear la tabla correspondiente en la base de
datos (llamada =contactos=) y que tiene los si$uientes camposB
-omo podemos ver la tabla y los nombres de las columnas se $eneran en base al arc"ivo de mapeo.
En donde "emos colocado los nombres de las columnas se "an usado estos nombres, en donde no lo
"emos "ec"o se "an tomado los mismos nombres que el de los atributos que estamos mapeando.
(i observamos la salida de la consola podemos ver, que en la parte final, se indica esta creacin y
adems las consultas que 8ibernate "a $enerado (revueltas con los mensa#es que sacamos a
consola). 8e marcado con ro#o los mensa#es que mandamos a consola para que sea fcil
distin$uirlos.
(e$un indica la salida en la base de datos solo debemos tener dos entidades, con los nombres
='uevo -ontacto ?= y =-ontacto >=. )evisemos la tabla para ver que esto sea correctoB
-omo podemos ver, esto es correcto, en la base de datos e%isten solo los re$istros indicados, con lo
que podemos estar se$uros de que nuestra aplicacin funcionaUUU NCN.
Entonces, vimos que con 8ibernate fue muy simple "acer la manipulacin de los datos de una base
de datos relacional sin escribir una sola lnea de (+. En aplicaciones de tama.o mediano a $rande
esto nos a"orrar muc"o tiempo (que normalmente usaramos en escribir el (+ para query, armar
al$unas de estas de forma dinmica, pasar los parmetros adecuados, recuperar los mismos de un
)esult(et, entre otras cosas) para me#orar al$unos otros aspectos de la aplicacin, como la interfa!
$rfica, la l$ica del ne$ocio, o reali!ar ms pruebas. 3dems nuestro cdi$o es ms simple y por lo
tanto fcil de mantener.
o nico malo es que a"ora tenemos que crear mapeos de las entidades con las tablas de la base de
datos en un arc"ivo 9/. Es por esto que en el si$uiente tutorial veremos cmo reali!ar este
mismo e#emplo pero usando anotaciones en ve! del arc"ivo de mapeo NCN.
Espero que esto les "aya sido de utilidad. 'o olviden de#ar sus comentarios, dudas, y su$erencias.
(aludos.
,escar$a los arc"ivos de este tutorial desde aquB
8ibernate 3rc"ivos de /apeo

Potrebbero piacerti anche