martes, 3 de noviembre de 2009

Integración Spring y Hibernate (1)

La integracion de Hibernate con Spring es muy sencilla, se puede hacer de varias formas. Aquí vamos a ver la primera y mas simple.

Creamos una tabla Persona con la siguiente estructura

CREATE TABLE PERSONA (
NOMBRE VARCHAR(10),
APELLIDOP VARCHAR(20),
EDAD INTEGER
);

La estructura de este ejemplo es



Para obtener un sessionFactory usamos la clase HibernateUtil.java que se define como sigue

package org.dracof.hibernate.util;

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

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static {
sessionFactory =
new Configuration().configure().buildSessionFactory();
}

public static SessionFactory getSessionFactory () {
return sessionFactory;
}
}

El mapeo de hibernate (Persona.hbml.xml) con la tabla Persona se realiza como sigue

<hibernate-mapping>
<class name="org.dracof.hibernate.Persona" table="PERSONA">
<id name="nombre" column="NOMBRE">
<generator class="assigned"/>
</id>
<property name="apellidoP" column="APELLIDOP"/>
<property name="edad" column="EDAD"/>
</class>
</hibernate-mapping>

Se crea el POJO para este mapeo

public class Persona {

private String nombre;

private String apellidoP;

private Integer edad;

//setters y getters
...
}

Definimos la interface para el DAO

package org.dracof.hibernate.dao;

import org.dracof.hibernate.Persona;

public interface PersonaDAO {

public void creaPersona (Persona persona);

public Persona obtienePersona (String nombre);

public void eliminaPersona (String nombre);
}

Y su implementacion

package org.dracof.hibernate.dao.impl;

import org.dracof.hibernate.Persona;
import org.dracof.hibernate.dao.PersonaDAO;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class PersonaDAOImpl implements PersonaDAO {

private SessionFactory sessionFactory;

public void setSessionFactory (SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

public void creaPersona (Persona persona) {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save(persona);
session.getTransaction().commit();
}

public Persona obtienePersona (String nombre) {
Session session = sessionFactory.getCurrentSession();

session.beginTransaction();
Persona persona = (Persona)session.get(Persona.class, nombre);
session.getTransaction().commit();

return persona;
}

public void eliminaPersona (String nombre) {
Persona persona = new Persona();
persona.setNombre(nombre);

Session session = sessionFactory.getCurrentSession();

session.beginTransaction();
session.delete(persona);
session.getTransaction().commit();
}
}

En este caso vemos que se le inyecta el sessionFactory con Spring.

El XML de configuración para hibernate es

<?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">

<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">
org.apache.derby.jdbc.ClientDriver
</property>
<property name="connection.url">
jdbc:derby://localhost:1531/dracof
</property>
<property name="connection.username">dracof</property>
<property name="connection.password">dracof</property>

<property name="current_session_context_class">
thread
</property>
<property name="dialect">
org.hibernate.dialect.DerbyDialect
</property>
<property name="show_sql">true</property>

<mapping resource="org/dracof/hibernate/Persona.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Con ayuda de Spring se inyecta el sessionFactory

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="sessionFactory" factory-method="getSessionFactory"
class="org.dracof.hibernate.util.HibernateUtil"/>

<bean id="personaDAO"
class="org.dracof.hibernate.dao.impl.PersonaDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>

Podemos usar el factory-method para obtener el sessionFactory desde HibernateUtil, por ultimo se crea una clase para probar lo programado

package org.dracof.test;

import org.dracof.hibernate.Persona;
import org.dracof.hibernate.dao.PersonaDAO;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.
ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {
String appxml = "applicationContext.xml";
ApplicationContext context =
new ClassPathXmlApplicationContext( appxml );

PersonaDAO personaDAO =
(PersonaDAO)context.getBean("personaDAO");

//Creacion de Persona
Persona persona = new Persona();
persona.setNombre("Juan");
persona.setApellidoP("Perez");
persona.setEdad(50);
personaDAO.creaPersona( persona );

//Obtencion de Persona
persona = null;
persona = personaDAO.obtienePersona("Juan");
System.out.println( "Apellido de Juan: " +
persona.getApellidoP() );

Borrado de Persona
personaDAO.eliminaPersona( "Juan" );
}
}

Si ejecutamos el Test la salida es la siguiente

log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into PERSONA (APELLIDOP, EDAD, NOMBRE) values (?, ?, ?)
Hibernate: select persona0_.NOMBRE as NOMBRE0_0_, persona0_.APELLIDOP as APELLIDOP0_0_, persona0_.EDAD as EDAD0_0_ from PERSONA persona0_ where persona0_.NOMBRE=?
Apellido de Juan: Perez
Hibernate: select persona_.NOMBRE, persona_.APELLIDOP as APELLIDOP0_, persona_.EDAD as EDAD0_ from PERSONA persona_ where persona_.NOMBRE=?
Hibernate: delete from PERSONA where NOMBRE=?

Con este ejercicio tambien se puede omitir la construccion de la clase HibernateUtil modificando el applicationContext.xml inyectandole a la propiedad configLocation de
LocalSessionFactoryBean el valor classpath:hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="sessionFactory"
class="org.springframework.orm.
hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml"/>
</bean>

<bean id="personaDAO"
class="org.dracof.hibernate.dao.impl.PersonaDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>

Para esta configuracion conservamos completamente el archivo hibernate.cfg.xml, en otros casos solo lo podemos usar para el mapeo de recursos y en otros casos se puede hasta eliminar este archivo y escribir la configuración en el applicationContext.xml.


Codigo Java
Script SQL

Suerte.

2 comentarios:

  1. EN PersonaDAOImpl EL sessionFactory ME SALE CON VALOR NULL

    ResponderEliminar
  2. Joven Samuel, publique su codigo de configuracion y como lo esta llamando.

    ResponderEliminar