• No se han encontrado resultados

Integración de Hibernate en Spring

In document Evaluación de Spring MVC (página 67-71)

4.3 Simplificación del JDBC

6. Integración de Hibernate en Spring

En el mercado existen diversas plataformas para dar solución a un sistema de persistencia basado en mapeo de modelos de objeto relacionales (ORM). Spring es compatible con varios frameworks entre ellos se encuentra Hibernate. Spring aporta compatibilidad integrada para transacciones declarativas de Spring, manejo de excepciones, plantillas, soporte DAO y gestión de recursos.

Hibernate es el framework que más acogida ha tenido dentro de la comunidad, siendo este de código abierto y desarrollado en un principio por desarrolladores dispersos alrededor del mundo. No solo otorga ORM, sino que también ofrece soluciones al duplicado de datos, la carga perezosa, eager fetching y duplicado de datos.

Un aspecto importante que hay que tener en cuenta es elegir la versión de Hibernate, al margen de las nuevas funcionalidades, ya que el nombre de los paquetes varía de la versión 2 a la 3 y esto hace que haya que diferenciarlos en Spring. Así para Hibernate 2 se utilizaran las clases contenidas en org.springframework.hibernate, para Hibernate 3 se utilizaran las clases en el paquete org.springframework.hibernate3.

6.1. Instanciar SessionFactory de Hibernate

El objeto LocalSessionFactoryBean de Spring es un bean factory de Spring que produce una instancia local de SessionFactory de Hibernate que toma sus parámetros de mapeo de los archivos XML.

64

<bean id="localSessionFactory"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean "> <property name="dataSource" ref="dataSource"/>

<property name="mappingResources"> <list> <value>es/tfg/hibernateaddendum/model/Exam.hbm.xml</value> <value>es/tfg/hibernateaddendum/model/Student.hbm.xml</value> <value>es/tfg/hibernateaddendum/model/Subject.hbm.xml</value> <value>es/tfg/hibernateaddendum/model/SubjectUnit.hbm.xml </value> </list> </property>

<property name="hibernateProperties"> <prop>

<prop key="hibernate.dialect">${hibernate.dialect}</prop> </props>

</property> </bean>

La propiedad mappingResources define una lista con una entrada por fichero hbm.xml que se definirá para el mapeo del objeto relacional. La propiedad hibernateProperties define propiedades necesarias para la configuración de Hibernate.

6.2. AnnotationSessionFactoryBean

Si lo que se desea es utilizar objetos cuyas clases implementen anotaciones JPA y anotaciones específicas de Hibernate se debe usar la clase AnnotationSessionFactoryBean. Es muy similar a la clase LocalSessionFactoryBean salvo que en vez de hacer una lista con los ficheros hbm.xml la haremos con cada objeto que implemente anotaciones.

<bean id="annotationSessionFactoryBean"

class="org.springframework.orm.hibernate3.annotation.AnnotationSession FactoryBean ">

<property name="dataSource" ref="dataSource"/> <property name="AnnotatedClasses">

<list> <value>es.tfg.hibernateaddendum.model.Exam</value> <value>es.tfg.hibernateaddendum.model.Student</value> <value>es.tfg.hibernateaddendum.model.Subject</value> <value>es.tfg.hibernateaddendum.model.SubjectUnit</value> </list> </property>

<property name="hibernateProperties"> <prop>

<prop key="hibernate.dialect">${hibernate.dialect}</prop> </props>

</property> </bean>

65

Como se puede ver en el ejemplo anterior la definición es muy similar a LocalSessionFactoryBean, salvo que hay que tener una propiedad annotatedClasses cuya lista se confecciona con las clases con anotaciones persistentes.

6.3. Hibernate Template

Esta plantilla simplifica el trabajo con el objeto Session de Hibernate, siendo responsable de abrir y cerrar las sesiones y de gestionar las excepciones. Para crear la plantilla hay que pasar una instancia de la FactorySession.

El siguiente fragmento muestra cómo se configura Hibernate Template en Spring:

<bean id="hibernateTemplate"

class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="localSessionFactory"/> </bean>

Y el siguiente fragmento sería para utilizar el annotationSessionFactoryBean definido anteriormente:

<bean id="hibernateTemplate"

class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory"

ref="annotationSessionFactoryBean"/> </bean>

Ambas definiciones son idénticas, cabe señalar que en el atributo sessionFactory se podrá pasarle cualquier clase que implemente FactoryBean.

Una vez hecho todo habrá que crear un DAO que haga uso de la plantilla para que así se pueda persistir y recuperar objetos.

El siguiente código sirve de ejemplo de cómo se hace uso de la plantilla.

public class HibernateExamsDaoImp {

private static final String INSERT=“insert”;

private static final String DELETE=“delete”;

private static final String GETT_EXAM=“getExam”;

private static final String EXAM=EXAM.class.getName();

private static final String SELECT_ID=“from” + EXAM +

“where id = ?“;

private static final String SELECT_ALL=“from” + EXAM;

private HibernateTemplate hibernateRemplate;

public HibernateTemplate getHibernateTemplate(){

return hibernateTemplate; }

public void setHibernateTemplate(HibernateTemplate

hibernateTemplate){ this. hibernateTemplate= hibernateTemplate;

66

}

public void update(Exam exam){

getHibernateTemplate().saveorUpdate(exam); }

public void insert(Exam exam){

getHibernateTemplate().saveorUpdate(exam); }

public void insert(Set<Exam> exams) throws ExamsException{ for(Iterator<Exam> it = exams.iterator(); it.hasNext();){

this.insert(it.next()); }

}

public void getExam(int id) throws ExamsException{

List results = getHibernateTemplate().find(SELECT_ID,id); if(results.size()==0){

return (Exam) results.get(0); }

throws new ExamNotFoundException(id); }

public Collection<Exam> getAllExams() throws ExamsException{ return getHibernateTemplate().find(SELECT_ALL);

}

public void delete(int id) throws ExamsException{

getHibernateTemplate().delete(this.getExam(id)); }

}

Así las operaciones monótonas necesarias para operar con Hibernate serán controladas por la plantilla.

La definición dentro del contenedor de Spring se hará de la siguiente forma:

<bean id="hibernateExamsDaoImp"

class="es.tfg.hibernatespringintegration.dao.HibernateExamsDaoImp"> <property name="hibernateTemplate" ref="hibernateTemplate"/> </bean>

6.4. HibernateDaoSupport

Al igual que con JdbcDaoSupport, Spring también facilita la construcción de DAO en Hibernate. La clase HibernateDaoSUpport otorga una plantilla HibernateTemplate con lo que sólo tendremos que inyectar un objeto SessionFactory.

El siguiente código pertenece a la clase HibernateStudentsDaoImp que hereda de HibernateDaoSupport:

67

public class HibernateStudentsDaoImp extends HibernateDaoSupport{

private static final String STUDENT=Student.class.getName();

private static final String SELECT_ID=“from” + STUDENT +

“where id = ?“;

private static final String SELECT_ALL=“from” + STUDENT;

public void update(Exam student){

getHibernateTemplate().saveorUpdate(student); }

public void insert(Exam student){

getHibernateTemplate().saveorUpdate(student); }

public void insert(Set<Student> students)

throws StudentsException{ for(Iterator<Exam> it = students.iterator();

it.hasNext();){ this.insert(it.next());

} }

public void getStudent(int id) throws ExamsException{

List results = getHibernateTemplate().find(SELECT_ID,id); if(results.size()==0){

return (Student) results.get(0); }

throws new StudentNotFoundException(id); }

public Collection<Student> getAllStudents()

throws StudentsException{ return getHibernateTemplate().find(SELECT_ALL);

}

public void delete(int id) throws ExamsException{

getHibernateTemplate().delete(this.getStudent(id)); }

}

Con las clases de soporte Spring se facilita al máximo la codificación de las nuevas clases reduciendo el número de líneas de código de estas y reduciéndolas a la mínima expresión.

In document Evaluación de Spring MVC (página 67-71)