miércoles, 15 de septiembre de 2010

Java Persistence API con Hibernate.

Saludos compañeros y gracias por acompañarme nuevamente, acá en Acerca de Java para discutir temas acerca de la tecnología java. Ahora hablemos un poco acerca de Java Persistence Api (JPA), en su implementación Hibernate.

Generalmente cuando creamos aplicaciones, debemos interactuar con una base de datos relacional, en este caso es necesario realizar sentencias SQL desde nuestro código de programa para poder enviar solicitudes de base de datos y traer, actualizar o borrar datos.

Con la implementación Hibernate, ya esto no es necesario. Hibernate me permite realizar persistencias de objetos java en una base de datos relacional sin necesidad de sentencias sql, es decir puedo almacenar mi objeto java, en una base de datos, relacionando mis datos de objeto con los campos de la base de datos.

Para poder realizar este tipo de persistencia se necesitan cinco requisitos:

* Objeto Java Persistente: Objeto a ser serializado.
* Archivo de Mapeo Hibernate:
* Archivo de Configuración Hibernate.
* API Hibernate.
* Manejador de Base de Datos, en este caso yo utilizaré PostgreSQL 9.0.

Objeto Java Persistence: Una innovación con Hibernate es que no necesita extender a ninguna clase y tampoco es necesario que implemente una interfaz. Pero si es necesario declarar un constructor público que no reciba parámetros, además como buena práctica de programación deben sobreescribir los métodos equals y hashCode, no es un requisitor indispensable pero se considera buena práctica de programación.

Ejemplo de un tipo de objeto persistente:


package mypersistence;

import java.util.Date;

public class Empleado {

private int id;
private String nombre;
private Date nacimiento;

public Empleado(){ }

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public Date getNacimiento(){
return nacimiento;
}

public boolean equals(Object objeto){
if(objeto == this)
return true;
Empleado empleado = (Empleado) objeto;
if(this.nombre.equals(empleado.nombre))
return true;
return false;
}

public int hashCode(){
return this.nombre.hashCode();
}

public void setNacimiento(Date fecha) {
nacimiento = fecha;
}
}


Archivo de mapeo Hibernate: Es un archivo XML que que dice al API Hibernate como va a ser serializado mi Objeto Java Persistence. Hay 4 maneras:
* Mapeo de clase a tabla.
* Un elemento id para identificar la clave principal de la tabla.
* Mapeo de propiedad a columna o lo que es lo mismo de Atributo a campo.
* Relaciones con otros objetos persistentes.

Ejemplo de XML:
Nombre del archivo: Empleado.hbm.xml




<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd ">

<hibernate-mapping>
<class name = "mypersistence.Empleado" table="Empleados">

<id name = "id" column = "id">
<generator class="sequence"/>
</id>

<property name = "nombre" column = "nombre"
type = "string"></property>
<property name = "nacimiento" column = "fecha_nacimiento"
type = "timestamp" update = "false"></property>

</class>
</hibernate-mapping>


Archivo de configuracion Hibernate: Como es de esperarse este archivo define las opciones de configuración globales para la serialización y por ello normalmente sólo existe un archivo XML de configuración por aplicación. Aquí se definen: Información sobre la conexión a la base de datos, dialecto a utilizar (varía de acuerda al RDBMS utilizado), una opción que es bueno resaltar es la propiedad show_sql que muestra el SQL que ha sido ejecutado además hibernate.hbm2dll.auto crea las tablas basado en el archivo de mapeo. Aquí ahora el ejemplo de archivo de configuración hibernate:

Nombre del archivo: hibernate.cfg.xml


<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd ">

<hibernate-configuration>
<session-factory>
<property name = "show_sql">true</property>
<property name = "hibernate.dialect">
org.hibernate.dialect.PostgreSQLDialect</property>
<property name = "hibernate.hbm2dll.auto">
create-drop</property>
<property name = hibernate.connection.driver_class">
org.postgresql.Driver</property>
<property name = "hibernate.connection.username">
postgres</property>
<property name = "hibernate.connection.password">
miclave</property>
<property name = "hibernate.connection.url">
jdbc:postgresql://localhost:5432/postgres</property>
<mapping resource = "Empleado.hbm.xml" />
</session-factory>
</hibernate-configuration>


API Hibernate: Es el conjunto de herramientas que me permite realizar la serialización, es decir, esta es la maquinaria necesaria para utilizar todos los otros tres recursos antes vistos e implementar de una vez la serialización. En nuestro caso vamos a utilizar el paquete org.hibernate.*.

Veamos ahora que debemos hacer para utilizar este API Hibernate y realizar la serialización:

Creación de HibernateUtil: interactúa con el archivo de configuración. Inicia sesión.



package mypersistence;

import java.io.File;

import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;

public class HibernateUtil {
private final static SessionFactory sf;
static {
Configuration cfg = new Configuration();
File f = new File(
"C:\\AcercaDeJava\\Hibernate\\files\\hibernate.cfg.xml");
cfg.configure(f);
sf = cfg.buildSessionFactory();
}

public static Session currentSession(){
return sf.openSession();
}

public static void close(Session session){
session.close();
}
}


HibernateManager: Utiliza a HibernateUtil para iniciar sesión e inicia el proceso de grabación:


package mypersistence;


import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import mypersistence.Empleado;
import mypersistence.HibernateUtil;

public class EmpleadoManager {

Session s = HibernateUtil.currentSession();

public void save(Empleado empleado){
try{
Transaction tx = s.beginTransaction();
s.saveOrUpdate(empleado);
tx.commit();
}catch(HibernateException e){
e.printStackTrace();
}
}

public static void main(String[] args) {
Empleado empleado = new Empleado();
empleado.setNombre("Rafael Atencio");
empleado.setNacimiento(new Date());

EmpleadoManager manager = new EmpleadoManager();
manager.save(empleado);
}
}


Ahora si: Aquí tengo una lista de las librerías que tuve que usar, casi todas pueden encontrarse en la página web http://www.findjar.com/index.x:

cglib-full-2.0.jar
commons-collections-3.1.jar
commons-logging-api.jar
dom4j-1.1.jar
ehcache-1.6.2.jar
hibernate-3.0.5.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar
hibernate-validator-4.1.0.Final.jar
j2ee-1.4.jar
log4j-1.2.14.jar
postgresql-9.0-801.jdbc4.jar
slf4j-api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
validation-api-1.0.0.GA.jar

Además hay que asegurarse que la ruta de los archivos hibernate.cfg.xml y Empleado.hbm.xml están en el Build Path o CLASSPATH.

Para ello, en eclipse, se hace clic secundario Proyecto, se elige el Build Path, luego Configure Build Path..., se va a la prestaña Source y se agrega la carpeta donde están los archivos de mapeo y configuración.

Adicionalmente como PostgreSQL no trabaja directamente con campos AUTOINCREMENT hay que realizar un objeto de secuencia hibernate ejecutando la siguiente sentencia SQL en nuestra BD Postgres:



CREATE SEQUENCE hibernate_sequence
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;


Bueno no queda más que ejecutar la clase HibernateManager para generar un registro en Base de Datos PostgreSQL y obtener por consola el SQL que ha sido ejecutados.

Por ahora no tengo más que decir más que desearle suerte en la ejecución de su proyecto con Hibernate, cualquier duda pueden escribir comentarios en el post.

Nos vemos, ¡Hasta Luego!

5 comentarios:

Anónimo dijo...

SI tiene auoincrement declara tu variable como Serial

edison dijo...

hola que tal Kelvin muchos saludos....queria pedirte si prodrias hablar en tus blogs sobre patrones de diseño ya que en este semestre estoy estudiando ese tema te lo agradeceria mucho....
y suigue adelante tus blogs son muy buenos.....

edison dijo...

de ante mano te agradesco un monton.....Suerte

Kelvin dijo...

Saludos Edison, en el siguiente enlace podrás ver el primer artículo acerca del patrón de diseño Singleton. Un patrón muy utilizado en Java.

Patrón de diseño: Singleton
Hasta Luego

Kelvin dijo...

También en este enlace podrás ver el patrón de diseño: Adaptador.

Patrón de diseño: Adaptador
Hasta Luego