Proyecto con JSF Java Server Faces Myfaces, Maven y Eclipse: Hibernate (segunda parte)

0
38315

 

 

Proyecto con JSF Java Server Faces Myfaces, Maven y

Eclipse: Hibernate

 

Proyecto con

JSF Java Server Faces Myfaces, Maven y Eclipse: Hibernate. 1

Introducción. 1

Requisitos. 1

Introducción

de Hibernate en la aplicación. 2

Creación de

la base de datos de la aplicación. 2

Añadir un

módulo estándar al proyecto: hibernate, driver de mysql, etc. 6

Añadir el

driver de MySql al proyecto. 6

Añadir las

dependencias de Hibernate al proyecto. 9

Instalación

manual del Sun JTA.. 10

Añadiendo

los nuevos módulos a Eclipse. 13

Creación del

fichero de configuración de Hibernate. 13

Añadiendo un

panel de control de las hibernate tools. 16

Creando las

clases java con las hibernate tools. 20

Refinando la

generación de las clases con el fichero revenge.xml 27

Añadiendo el

soporte para Hibernate 3 en el proyecto coregest-core. 34

Añadiendo la

persistencia a nuestra aplicación sobre el módulo de la lógica de negocio. 35

Creando la

configuración de Hibernate para las pruebas unitarias. 35

Creando la

inicialización de Hibernate con nuestro HibernateUtil 36

Creando la

primera clase a persistir: register 37

Pruebas

unitariasdel módulo coretest-core usando Hibernate. 40

Ejecutando

las pruebas unitarias en Maven. 42

Prueba de la

aplicación desde un tomcat externo. 45

Enlaces de

interés. 45

 

Introducción

 

Este tutorial sigue la serie de tutoriales sobre MyFaces JSF

y Maven, en entorno Eclipse. En esta ocasión vamos a introducir Hibernate 3.2

con anotaciones en nuestro proyecto, todo ello respetando la filosofía de

Maven, e integrándolo en Eclipse. Algunas de las cosas que vamos a ver son:

  • Añadir los módulos de hibernate a nuestros proyectos Maven
  • Configurar Eclipse para utilizar Hibernate en proyectos

    Maven

  • Configurar Hibernate en nuestro módulo de lógica de

    negocio

  • Crear pruebas unitarias de persistencia para nuestro módulo

    de negocio,

  • Crear una instancia de Tomcat para probar nuestra

    aplicación

Requisitos

 

Introducción de Hibernate en la aplicación

 

Creación de la base de datos de la aplicación

 

Lo primero que vamos a hacer es crear la base de datos

coregest en la instancia de MySql local. Abrimos el administrador de MySql

 

 

Pulsamos OK

 

 

Pulsando seobre el fondo con el botón secundario elegimos

“Create a new Schema”

 

 

Pulsamos OK

 

 

Ahora hay que crear las tablas. Vamos a usar las tablas

descritas en el artículo del gestor documental, con alguna variación

 

 

Pulsamos en “Apply changes”

 

 

Y nos muestra el SQL necesario para generar la tabla.

 

 

CREATE TABLE `coregest`.`register` (

  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,

  `nreg` VARCHAR(45) NOT NULL,

  `version` INTEGER UNSIGNED NOT NULL,

  `name` VARCHAR(45) NOT NULL,

  `desc` VARCHAR(45) NOT NULL,

  `type` VARCHAR(45) NOT NULL,

  `dateCreation` DATETIME NOT NULL,

  PRIMARY KEY (`id`)

)

ENGINE = InnoDB;

 

Cerramos la ventana y nos muestra la tabla creada

 

 

Procederemos de igual manera con el resto de las tablas.

Añadir un módulo estándar al proyecto: hibernate,

driver de mysql, etc.

Lo primero que debemos hacer es localizar el módulo que

queremos añadir. Vamos a comenzar por el driver de MySql. Le echamos un vistazo

a la página

 

http://www.ibiblio.org/maven/

 

y vemos que nos muestra una estructura de carpetas muy

amplia. Localizamos la carpeta mysql y vemos que en ella hay varias carpetas:

jars, licenses y poms. Dentro de jars está la carpeta

mysql-connector-java-5.0.5 (hay más, pero me quedo con la última versión del

driver) y hay en la carpeta poms el fichero mysql-connector-5.0.5.pom. Ya tengo

toda la información que necesito:

  • groupId = mysql (es el nombre de la carpeta desde

    ibiblio.org/maven)

  • artifactId= mysql-connector-java (el nonbre del jar sin la

    versión ni extensión)

  • version=5.0.5 (el que hayamos elegido)

 

Investigando un poco en la carpeta maven veremos el

hibernate y otros módulos interesantes (hay cientos…). Algunas carpetas tienen

nombres largos tipo net.sf.jaspereports, que habrá que colocar convenientemente

en el groupId.

Añadir el driver de MySql al proyecto

Para añadir el driver de MySql lo vamos a hacer siguiendo el

estándar de Maven. Para ello modificamos el POM del módulo coregest-core,

añadiéndole las dependencias pertinentes:

 

Coregest-core\pom.xml

<project

xmlns=»http://maven.apache.org/POM/4.0.0″

xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»

  xsi:schemaLocation=»http://maven.apache.org/POM/4.0.0

http://maven.apache.org/maven-v4_0_0.xsd»>

  <modelVersion>4.0.0</modelVersion>

  <groupId>net.sf.coregest</groupId>

  <artifactId>coregest-core</artifactId>

  <packaging>jar</packaging>

  <version>1.0-SNAPSHOT</version>

  <name>coregest-core</name>

  <url>http://maven.apache.org</url>

  <dependencies>

            <dependency>

                        <groupId>mysql

</groupId>

                        <artifactId>mysql-connector-java</artifactId>

                        <version>5.0.5</version>

                        <scope>compile</scope>

            </dependency>

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

      <version>3.8.1</version>

      <scope>test</scope>

    </dependency>

  </dependencies>

</project>

 

Probamos a instalar el módulo coregest-core.

 

 

Automáticamente se descargará e instalará en el repositorio

local el jar del driver de mysql:

 

 

Como vemos, el repositorio local se va poblando poco a poco

con los módulos necesarios.

Ahora instalamos el paquete coregest (la aplicación web)

para ver si se copia también el driver en la aplicación

 

 

En la carpeta coregest\target\coregest\web-inf\lib vemos que

no lo copia, luego si necesitamos incluirlo en el paquete war hay que añadirlo

a las dependencias del segundo módulo también. Esto dependerá de si queremos incluir

el driver en el  war o no (por ejemplo, por motivos de licencias). También se

puede añadir en un pom del que hereden ambos proyectos, que es un mecanismo

diseñado en Maven para proyectos con muchos módulos. Si queremos añadir el

driver al war añadimos la dependencia al coregest\pom.xml.

Añadir las dependencias de Hibernate al proyecto

Para añadir hibernate al proyecto hacemos lo mismo. Esta

vez, buscando en ibiblio obtenemos (si usamos anotaciones son dos dependencias):

  • groupId = org.hibernate (el groupId hibernate tiene

    versiones más antiguas)

  • artifactId = hibernate, hibernate-annotations (si vamos a

    usar anotaciones)

  • version = 3.2.0.ga (hay varias combinaciones posibles, ver

    hibernate.org). Elegimos una.

 

Nos quedan así los pom de los módulos:

 

….   

        <dependency>

                        <groupId>org.hibernate</groupId>

                        <artifactId>hibernate</artifactId>

                        <version>3.2.0.ga</version>

                        <scope>compile</scope>

            </dependency>

            <dependency>

                        <groupId>org.hibernate</groupId>

                        <artifactId>hibernate-annotations</artifactId>

                        <version>3.2.0.ga</version>

                        <scope>compile</scope>

            </dependency>

 

También hay que añadirlas al coregest ya que nos interesa

que en el war vayan los jar de hibernate.

 

Si ahora hacemos un mvn install del proyecto coregest-core

nos sale:

 

 

Esto se debe a que por motivos de licencia no está en

ibiblio el módulo jta de sun.com. Hay que instalarlo a mano. Siguiendo las

instrucciones en pantalla, localizamos el jar en sun.com. Probablemente las

limitaciones de las licencias de Sun impiden la inclusión de estas bibliotecas

en ibiblio.org.

 

Instalación manual del Sun JTA

Nos conectamos a sun.com y localizamos el zip de JTA 1.0.1B

 

Descargamos el fichero jta-1_0_1B-classes.zip a una carpeta

local, en mi caso d:\apps y lo instalamos en nuestro repositorio local con

 

      mvn install:install-file -DgroupId=javax.transaction

-DartifactId=jta

          -Dversion=1.0.1B -Dpackaging=jar -Dfile=d:/apps/

jta-1_0_1B-classes.zip

 

 

Y se nos instala en local, como podemos comprobar en nuestro

repositorio local

 

 

Observamos que además lo ha convertido en un jar.

 

Ahora ya podemos hacer un mvn install sobre los dos módulos

y comprobar que todo ha ido bien. El war debe contener los módulos de hibernate:

 

 

Esto va teniendo buena pinta.

 

Añadiendo los nuevos módulos a Eclipse

Ya que hemos añadido varios jar al proyecto, hay que

actualizar la configuración de los proyectos en Eclipse.  Esto lo haremos con

mvn eclipse:eclipse (con el Eclipse cerrado).

 

 

Y se nos añaden al “Java build path” del Eclipse. Abrimos el

Eclipse

 

 

Procedemos de igual manera con coregest-core. Como veis,

usar Maven facilita mucho las cosas.

Creación del fichero de configuración de Hibernate

 

Ahora vamos a introducir Hibernate en la aplicación. Ya que

hemos dividido la aplicación separando la lógica de negocio en un módulo

separado, será en este módulo en el que añadiremos la configuración de

Hibernate.

Vamos a comenzar por una configuración simple, siguiendo el

tutorial de Alejando Pérez sobre las Hibernate Tools. Lo primero es crear un

fichero de configuración de Hibernate, en la carpeta resources de nuestro

proyecto (si no exites, creamos coregest-core/src/main/resources). Pulsamos

sobre el proyecto coregest-core y creamos un nuevo ficero de configuración con

File\New…\Other..\Hibernate configuration file (cfg.xml)

 

 

Pulsamos “Next”

 

 

Ahora pulsamos “Next”

 

 

Rellenamos los campos adecuadamente y pulsamos “Finish”

 

Añadiendo un panel de control de las hibernate

tools

En este paso vamos a añadir un panel de control a nuestro

módulo coregest-core, de manera que podamos utilizar las hibernate tools sobre

él. Pulsamos en “File\New\Others…\Hibernate\Hibernate console configuration”

 

 

Pulsamos “Next”

 

Voy a usar anotaciones, por lo que se lo indico a la

consola.

 

Ahora hay que añadir la ruta al driver de mysql, para que

las hibernate tools puedan examinar la base de datos. Pulsamos en la pestaña

“Classpath”

 

 

He añadido el driver de mysql que tengo en el repositorio

local, con el botón “Add externa JAR”. También lo podría añadir del target del

módulo coregest si lo he incluido en el war. Nos sale un mensaje de aviso.

 

 

Pulsamo “Yes”. Creo que lo que hará será añadirle el nature

de hibernate al proyecto. Ummm, veamos:

 

 

Efectivamente, según sospechabamos le ha añadido el nature

de hibernate.

 

 

Creando las clases java con las hibernate tools

 

Buscamos el icono que permite lanzar el asistente de

genearción de código de las hibernate tools

 

 

Es pequeñito, cuesta verlo.

 

 

Pulsamos con doble clic sobre “Hibernate code configuration”

 

 

Ahora rellenamos los campos (para más información, leer el

tutorial de hibernate tools de Alejandro Pérez https://adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=hibernateTools

 

Ahora nos vamos a la pestaña de “Exporters”

 

 

En nuestro caso queremos utilizar las anotaciones de Java

5.0.

 

Pulsamos “Run”. No olvidar crear la carpeta generated-sources

y hacer un refresh (F5) del módulo coregest-core antes de ejecutar el “Run”.

 

 

Como vemos ha creado un par de archivos para la tabla

register. El texto del fichero generado es simple (nos interesa el

register.java)

 

Register.java

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

 

/**

 * Register generated by hbm2java

 */

@Entity

@Table(name = «register», catalog =

«coregest»)

public class Register implements java.io.Serializable {

 

            private int id;

 

            private int version;

 

            private String nreg;

 

            private String name;

 

            private String desc;

 

            private String type;

 

            private Date dateCreation;

 

            public Register() {

            }

 

            public Register(int id, String nreg, String

name, String desc, String type,

                                   Date dateCreation) {

                        this.id = id;

                        this.nreg = nreg;

                        this.name = name;

                        this.desc = desc;

                        this.type = type;

                        this.dateCreation = dateCreation;

            }

 

            @Id

            @Column(name = «id», unique = true,

nullable = false)

            public int getId() {

                        return this.id;

            }

 

            public void setId(int id) {

                        this.id = id;

            }

 

            @Column(name = «version», nullable =

false)

            public int getVersion() {

                        return this.version;

            }

 

            public void setVersion(int version) {

                        this.version = version;

            }

 

            @Column(name = «nreg», nullable = false,

length = 45)

            public String getNreg() {

                        return this.nreg;

            }

 

            public void setNreg(String nreg) {

                        this.nreg = nreg;

            }

 

            @Column(name = «name», nullable =

false, length = 45)

            public String getName() {

                        return this.name;

            }

 

            public void setName(String name) {

                        this.name = name;

            }

 

            @Column(name = «desc», nullable =

false, length = 45)

            public String getDesc() {

                        return this.desc;

            }

 

            public void setDesc(String desc) {

                        this.desc = desc;

            }

 

            @Column(name = «type», nullable =

false, length = 45)

            public String getType() {

                        return this.type;

            }

 

            public void setType(String type) {

                        this.type = type;

            }

 

            @Column(name = «dateCreation»,

nullable = false, length = 0)

            public Date getDateCreation() {

                        return this.dateCreation;

            }

 

            public void setDateCreation(Date dateCreation)

{

                        this.dateCreation = dateCreation;

            }

 

}

 

Podríamos simplificarlo, tal y como nos indica Alejandro.

 

Refinando la generación de las clases con el

fichero revenge.xml

Ahora vamos a crear el fichero revenge.xml tal y como se

indica en el tutorial de las hibernate tools. Pulsamos en “Hibernate code

generation” y en la pantalla de creación del código pulsamos el botón “Setup”

del campo “revenge.xml”

 

 

Al pulsar el botón nos pregunta si deseamos crear un nuevo

fichero

 

 

Pulsamos “Create new”

 

 

Seleccionamos la ruta y pulsamos “Next”

 

Al abrirse este cuadro de diálogo por primera vez se

mostrará en blanco. Pulsamos “Refresh” y se cargan las bases de datos

existentes.

Elegimos las tablas que queremos incluir en la generación de

código y pulsamos “Finish”

 

 

Ahora ya aparece la configuración de revenge.xml. Pulsamos

“Close”

 

 

Guardamos los cambios y volvemos a la pantalla principal de

Eclipse. Ahora vamos a buscar el fichero hibernate.revenge.xml en Eclipse y lo

abrimos. El editor predeterminado para este fichero es específico.

 

 

Nos vamos a la pestaña “Type mappings” para cambiar los

mapeos de tipos  de datos.

 

 

Pulsamos el botón “Refresh” y se cargan los datos de las

tablas. Pulsamos en el campo “id” de la primera tabla y luego el botón “Add…”.

Nos añade un mapeo de INTEGER  a “int”, que no nos interesa. Lo cambiamos por

“Integer”, tal y como se ve en la figura. También cambiamos en la última

columna el “Not null” a false (para que sea nullable, como nos sugiere Alex).

Esto genera un fichero hibernate.revenge.xml que podemos ver en la pestaña

source

 

 

 

Añadiendo el soporte para Hibernate 3 en el

proyecto coregest-core

 

Abrimos las propiedades del proyecto coregest-core y

seleccionamos la opción Hibernate

 

 

Activamos el soporte para Hibernate 3 y seleccionamos la

consola que debe usar Eclipse

 

Añadiendo la persistencia a nuestra aplicación

sobre el módulo de la lógica de negocio

En este apartado vamos a escribir los elementos básicos para

que nuestra aplicación sea capaz de persistir en la base de datos un objeto,

configurando el Hibernate y haciendo pruebas de su configuración.

 

Creando la configuración de Hibernate para las

pruebas unitarias

Para las pruebas unitarias he creado el siguiente fichero de

configuración, que he dejado en la carpeta coregest-core\src\test\resources

 

coregest-core\src\test\resources\hibernate.cfg.xml

<!DOCTYPE hibernate-configuration SYSTEM

«http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd»>

<hibernate-configuration>

       <session-factory>

             <property

name=»hibernate.connection.driver_class»>com.mysql.jdbc.Driver</property>

             <property

name=»hibernate.connection.url»>jdbc:mysql://localhost/coregest</property>

             <property

name=»hibernate.connection.username»>root</property>

              <property

name=»hibernate.connection.password»>sesamo</property>

             <property

name=»hibernate.dialect»>org.hibernate.dialect.MySQLDialect</property>

            

             <property

name=»hibernate.transaction.factory_class»>org.hibernate.transaction.JDBCTransactionFactory</property>

           <!–  thread is the short name for

org.hibernate.context.ThreadLocalSessionContext

                    and let Hibernate bind the

session automatically to the thread

                    Sinde Hibernate 3.1   

             –>

            

             <property

name=»hibernate.current_session_context_class»>thread</property>

            

            

             <!– Use the C3P0 connection pool

provider –>

             <!–

             <property

name=»hibernate.c3p0.min_size»>5</property>

             <property

name=»hibernate.c3p0.max_size»>20</property>

             <property

name=»hibernate.c3p0.timeout»>300</property>

              <property

name=»hibernate.c3p0.max_statements»>50</property>

             <property

name=»hibernate.c3p0.idle_test_period»>3000</property>

             –>

            

             <!– Show and print nice SQL on

stdout –>

             <property

name=»show_sql»>true</property>

             <property

name=»format_sql»>true</property>

            

             <!– List of XML mapping files

–>

             <mapping

class=»net.sf.coregest.core.model.Register»/>

       </session-factory>

</hibernate-configuration>

 

 

Para las pruebas unitarias no voy a usar C3PO (el pool de

conexiones) ya que en la configuración actual del proyecto no se incluye por

defecto. Creo que el entorno de pruebas de Maven sólo pone a disposición de la

aplicación de pruebas unitarias los jar que aparecen explícitamente en las

dependencias, y C3PO no está incluido. Nos lo apuntamos como deberes…

 

Además le vamos a añadir un fichero de logs mínimo

 

coregest-core\src\test\resources\logs4j.properties

# Direct log messages to stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.out

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE}?%5p %c{1}:%L %m%n

# Root logger option

log4j.rootLogger=INFO, stdout

# Hibernate logging options (INFO

only shows startup messages)

log4j.logger.org.hibernate=INFO

# Log JDBC bind parameter runtime

arguments

log4j.logger.org.hibernate.type=INFO

 

 

Creando la inicialización de Hibernate con nuestro

HibernateUtil

 

Para que podamos obtener una sesión de Hibernate se suele

crear una clase auxiliar llamada HibernateUtil, de la que hay muchos ejemplos

en Internet. Vamos a comenzar usando una versión simplificada y más adelante se

podrá sustituir por una versión threadsafe (segura en multihilos) y con soporte

para JNDI.

 

/coregest-core/src/main/java/net/sf/coregest/persistence/HibernateUtil.java

package net.sf.coregest.persistence;

import org.hibernate.*;

import org.hibernate.cfg.*;

 

public class HibernateUtil {

            private static SessionFactory sessionFactory;

           

            static {

                        try {

                                   System.out.println(«HibernateUtil

– constructor begin»);

                                   sessionFactory=new

AnnotationConfiguration().configure()

                                               .buildSessionFactory();

                        } catch (Throwable ex) {

                                   System.out.println(«HibernateUtil

– constructor error»);

                                   ex.printStackTrace();

                                   throw new ExceptionInInitializerError(ex);

                        }

                        System.out.println(«HibernateUtil

– constructor end»);

            }

 

            public static SessionFactory

getSessionFactory() {

                        // Alternatively, you could look

up in JNDI here

                       

                        return sessionFactory;

            }

           

            public static void shutdown() {

                        // Close caches and connection

pools

                        getSessionFactory().close();

            }

}

 

Para esta prueba hemos usado la clase que viene en el libro

“Java Persistence with Hibernate” (ver enlaces)

Creando la primera clase a persistir: register

La clase Register que hemos obtenido con las Hibernate Tools

la copiamos a su carpeta. Por conveniencia y para que esté actualizada, la

vuelvo a copiar aquí:

 

/coregest-core/src/main/java/net/sf/coregest/core/model/Register.java

package net.sf.coregest.core.model;

 

// Generated 12-jul-2007 19:03:24 by Hibernate Tools

3.2.0.b9

 

import java.util.Date;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

 

/**

 * Register generated by hbm2java

 */

@Entity

@Table(name = «register», catalog =

«coregest»)

public class Register implements java.io.Serializable {

 

            private long id;

 

//          private int version;

//

//          private int nreg;

//

            private String name;

//

//          private String desc;

//

//          private String type;

 

            private Date dateCreation;

 

            public Register() {

            }

 

            public Register(long id, int nreg, String

name, String desc, String type,

                                   Date dateCreation) {

                        this.id = id;

//                      this.nreg = nreg;

//                      this.name = name;

//                      this.desc = desc;

//                      this.type = type;

//                      this.dateCreation = dateCreation;

            }

 

            @Id

            @Column(name = «id», unique = true,

nullable = true)

            public Long getId() {

                        return this.id;

            }

 

            public void setId(long id) {

                        this.id = id;

            }

//

//          @Column(name = «version», nullable =

false)

//          public int getVersion() {

//                      return this.version;

//          }

//

//          public void setVersion(int version) {

//                      this.version = version;

//          }

//

//          @Column(name = «nreg», nullable =

false, length = 45)

//          public int getNreg() {

//                      return this.nreg;

//          }

//

//          public void setNreg(int nreg) {

//                      this.nreg = nreg;

//          }

//

            @Column(name = «name», nullable =

false, length = 45)

            public String getName() {

                        return this.name;

            }

 

            public void setName(String name) {

                        this.name = name;

            }

//

//          @Column(name = «desc», nullable =

true, length = 45)

//          public String getDesc() {

//                      return this.desc;

//          }

//

//          public void setDesc(String desc) {

//                      this.desc = desc;

//          }

//

//          @Column(name = «type», nullable =

true, length = 45)

//          public String getType() {

//                      return this.type;

//          }

//

//          public void setType(String type) {

//                      this.type = type;

//          }

 

            @Column(name = «dateCreation»,

nullable = true, length = 0)

            public Date getDateCreation() {

                        return this.dateCreation;

            }

 

            public void setDateCreation(Date dateCreation)

{

                        this.dateCreation = dateCreation;

            }

 

}

 

Como veis, para las pruebas he anulado algunos campos que

antes había definido. Además hay que configurar la base de datos para que los

campos sean nulab.es.

 

 

Sólo he puesto como no nulo el campo id.

Pruebas unitariasdel módulo coretest-core usando

Hibernate

Ahora nos creamos una clase de pruebas. Nuesto Maven nos ha

creado la clase AppTest.java, que vamos a modificar convenientemente:

 

/coregest-core/src/test/java/net/sf/coregest/AppTest.java

package

net.sf.coregest;

 

import

junit.framework.Test;

import

junit.framework.TestCase;

import

junit.framework.TestSuite;

 

import

java.util.Date;

import

java.util.Iterator;

import

java.util.List;

import

org.hibernate.HibernateException;

import

org.hibernate.Session;

import

org.hibernate.Transaction;

import

net.sf.coregest.core.model.*;

import

net.sf.coregest.persistence.HibernateUtil;;

 

 

/**

 *

Unit test for simple App.

 */

public

class AppTest

   

extends TestCase

{

   

/**

    

* Create the test case

    

*

    

* @param testName name of the test case

    

*/

   

public AppTest( String testName )

   

{

       

super( testName );

   

}

 

   

/**

    

* @return the suite of tests being tested

    

*/

   

public static Test suite()

   

{

       

return new TestSuite( AppTest.class );

   

}

 

  

 /**

    

* Rigourous Test 🙂

    

*/

   

/** prueba de listado e inserción de un registro con fecha */

   

public void testApp()

   

{

       

System.out.println(«testApp – Beginning»);

       

listRegisters();

       

System.out.println(«testApp  fin guardado un registro»);

             insertRetister(«Registro1»,

new Date());

             System.out.println(«testApp

– End»);

   

}

   

   

/** prueba de inserción de un registro sin fecha y listado */

   

public void testApp2() {

   

   System.out.println(«testApp2 – Beginning»);

   

   insertRetister(«Registro2», new Date());

   

   listRegisters();

   

   System.out.println(«testApp2 – End»);

      

   

}

   

   

/* clases de utilidad */

   

   

/** Lista todos los registros de tipo Register */

   

private void listRegisters(){

   

   System.out.println(«listRegisters – Begins»);

   

   Transaction tx = null;

             Session

session = HibernateUtil.getSessionFactory().getCurrentSession();

       

System.out.println(«listRegisters – Hibernate configured»);

       

       

try {

                    tx

= session.beginTransaction();

                    List

registros = session.createQuery(«select r from Register as

r»).list();

                    System.out.println(«Registros

leidos: » + registros.size());

                    for

(Iterator iter = registros.iterator(); iter.hasNext();) {

                           Register

element = (Register) iter.next();

                           //log.debug(element);

                           System.out.println(element);

                          

                    }

                    tx.commit();

             }

catch (HibernateException e) {

                    e.printStackTrace();

                    if

(tx != null && tx.isActive())

                           tx.rollback();

             }

             System.out.println(«listRegisters

– Ends»);

   

}

 

   

/**  Inserta un registro de tipo Register en la BD */

   

private void insertRetister(String name, Date date){

   

  

   

   System.out.println(«insertReegister – Beginning»);

       

Transaction tx = null;

             Session

session = HibernateUtil.getSessionFactory().getCurrentSession();

             System.out.println(«insertRegister 

getted session»);

            

             try

{

                    tx

= session.beginTransaction();

                           Register

r = new Register();

                           r.setName(name);

                           r.setDateCreation(date);

                           session.persist(r);

                           System.out.println(«insertRegister 

guardado el registro » + name);

                           tx.commit();

                           System.out.println(«insertRegister

cerrada la tx»);

                   

             }

catch (HibernateException e) {

                    e.printStackTrace();

                    if

(tx != null && tx.isActive())

                           tx.rollback();

             }

             System.out.println(«insertRegister

– End»);

   

  

   

}

   

   

}

 

Como vemos sólo hace un par de inserciones en la base de

datos coregest, que ahora sólo tiene una tabla: register.

 

Ejecutando las pruebas unitarias en Maven

Maven ejecuta las pruebas unitarias dentro de la fáse de

compilación e instalación del módulo, pero también las podemos llamar con mvn

test. Voy a ejecutar las pruebas con la base coregest vacía y capturo el

resultado, aunque es largo:

 

 

D:\workspace\WorkspaceCoregest\coregest-core>mvn

test

[INFO]

Scanning for projects…

[INFO]

————————————————————————-

[INFO]

Building coregest-core

[INFO]   

task-segment: [test]

[INFO]

————————————————————————-

[INFO]

[resources:resources]

[INFO]

Using default encoding to copy filtered resources.

[INFO]

[compiler:compile]

[INFO]

Nothing to compile – all classes are up to date

[INFO]

[resources:testResources]

[INFO]

Using default encoding to copy filtered resources.

[INFO]

[compiler:testCompile]

[INFO]

Nothing to compile – all classes are up to date

[INFO]

[surefire:test]

[INFO]

Surefire report directory: D:\workspace\WorkspaceCoregest\coregest-core\t

arget\surefire-reports

 

——————————————————-

 T

E S T S

——————————————————-

Running

net.sf.coregest.AppTest

testApp

– Beginning

listRegisters

– Begins

HibernateUtil

– constructor begin

25-jul-2007

23:40:33 org.hibernate.cfg.annotations.Version <clinit>

INFO:

Hibernate Annotations 3.2.0.GA

25-jul-2007

23:40:33 org.hibernate.cfg.Environment <clinit>

INFO:

Hibernate 3.2.0

25-jul-2007

23:40:33 org.hibernate.cfg.Environment <clinit>

INFO:

hibernate.properties not found

25-jul-2007

23:40:33 org.hibernate.cfg.Environment buildBytecodeProvider

INFO:

Bytecode provider name : cglib

25-jul-2007

23:40:33 org.hibernate.cfg.Environment <clinit>

INFO:

using JDK 1.4 java.sql.Timestamp handling

25-jul-2007

23:40:33 org.hibernate.cfg.Configuration configure

INFO:

configuring from resource: /hibernate.cfg.xml

25-jul-2007

23:40:33 org.hibernate.cfg.Configuration getConfigurationInputStream

 

INFO:

Configuration resource: /hibernate.cfg.xml

25-jul-2007

23:40:34 org.hibernate.cfg.Configuration doConfigure

INFO:

Configured SessionFactory: null

25-jul-2007

23:40:34 org.hibernate.cfg.AnnotationBinder bindClass

INFO:

Binding entity from annotated class: net.sf.coregest.core.model.Register

25-jul-2007

23:40:34 org.hibernate.cfg.annotations.EntityBinder bindTable

INFO:

Bind entity net.sf.coregest.core.model.Register on table register

25-jul-2007

23:40:34 org.hibernate.connection.DriverManagerConnectionProvider co

nfigure

INFO:

Using Hibernate built-in connection pool (not for production use!)

25-jul-2007

23:40:34 org.hibernate.connection.DriverManagerConnectionProvider co

nfigure

INFO:

Hibernate connection pool size: 20

25-jul-2007

23:40:34 org.hibernate.connection.DriverManagerConnectionProvider co

nfigure

INFO:

autocommit mode: false

25-jul-2007

23:40:34 org.hibernate.connection.DriverManagerConnectionProvider co

nfigure

INFO:

using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/coreges

t

25-jul-2007

23:40:34 org.hibernate.connection.DriverManagerConnectionProvider co

nfigure

INFO:

connection properties: {user=root, password=****}

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

RDBMS: MySQL, version: 5.0.22-community-nt

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.0.5 ( $

Date:

2007-03-01 00:01:06 +0100 (Thu, 01 Mar 2007) $, $Revision: 6329 $ )

25-jul-2007

23:40:34 org.hibernate.dialect.Dialect <init>

INFO:

Using dialect: org.hibernate.dialect.MySQLDialect

25-jul-2007

23:40:34 org.hibernate.transaction.TransactionFactoryFactory buildTr

ansactionFactory

INFO:

Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory

25-jul-2007

23:40:34 org.hibernate.transaction.TransactionManagerLookupFactory g

etTransactionManagerLookup

INFO:

No TransactionManagerLookup configured (in JTA environment, use of read-wr

ite

or transactional second-level cache is not recommended)

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Automatic flush during beforeCompletion(): disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Automatic session close at end of transaction: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

JDBC batch size: 15

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

JDBC batch updates for versioned data: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Scrollable result sets: enabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

JDBC3 getGeneratedKeys(): enabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Connection release mode: auto

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Maximum outer join fetch depth: 2

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Default batch fetch size: 1

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Generate SQL with comments: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Order SQL updates by primary key: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory createQueryTranslatorFact

ory

INFO:

Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory

25-jul-2007

23:40:34 org.hibernate.hql.ast.ASTQueryTranslatorFactory <init>

INFO:

Using ASTQueryTranslatorFactory

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Query language substitutions: {}

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

JPA-QL strict compliance: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Second-level cache: enabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Query cache: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory createCacheProvider

INFO:

Cache provider: org.hibernate.cache.NoCacheProvider

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Optimize cache for minimal puts: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Structured second-level cache entries: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Echoing all SQL to stdout

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Statistics: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Deleted entity synthetic identifier rollback: disabled

25-jul-2007

23:40:34 org.hibernate.cfg.SettingsFactory buildSettings

INFO:

Default entity-mode: pojo

25-jul-2007

23:40:34 org.hibernate.impl.SessionFactoryImpl <init>

INFO:

building session factory

25-jul-2007

23:40:35 org.hibernate.impl.SessionFactoryObjectFactory addInstance

INFO:

Not binding factory to JNDI, no JNDI name configured

HibernateUtil

– constructor end

listRegisters

– Hibernate configured

Hibernate:

   

select

       

register0_.id as id0_,

       

register0_.dateCreation as dateCrea2_0_,

       

register0_.name as name0_

   

from

       

coregest.register register0_

Registros

leidos: 0

listRegisters

– Ends

testApp 

fin guardado un registro

insertReegister

– Beginning

insertRegister 

getted session

insertRegister 

guardado el registro Registro1

Hibernate:

   

insert

   

into

   

    coregest.register

       

(dateCreation, name, id)

   

values

       

(?, ?, ?)

insertRegister

cerrada la tx

insertRegister

– End

testApp

– End

testApp2

– Beginning

insertReegister

– Beginning

insertRegister 

getted session

insertRegister 

guardado el registro Registro2

Hibernate:

   

insert

   

into

       

coregest.register

       

(dateCreation, name, id)

   

values

       

(?, ?, ?)

insertRegister

cerrada la tx

insertRegister

– End

listRegisters

– Begins

listRegisters

– Hibernate configured

Hibernate:

   

select

       

register0_.id as id0_,

       

register0_.dateCreation as dateCrea2_0_,

       

register0_.name as name0_

   

from

       

coregest.register register0_

Registros

leidos: 2

net.sf.coregest.core.model.Register@13c7378

net.sf.coregest.core.model.Register@1c0f2e5

listRegisters

– Ends

testApp2

– End

Tests

run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.094 sec

 

Results

:

 

Tests

run: 2, Failures: 0, Errors: 0, Skipped: 0

 

[INFO]

————————————————————————

[INFO]

BUILD SUCCESSFUL

[INFO]

————————————————————————

[INFO]

Total time: 5 seconds

[INFO]

Finished at: Wed Jul 25 23:40:35 CEST 2007

[INFO]

Final Memory: 4M/7M

[INFO]

————————————————————————

 

D:\workspace\WorkspaceCoregest\coregest-core>

 

Podemos ver varias cosas en el listado:

  • Al principio está la etapa de compilación, que variará

    según vayamos ejecutando los test.

  • Luego veremos que al ejecutar el test, en la primera

    llamada a HibernateUtil se configuara Hibernate.

  • Luego veremos cómo se van haciendo las consultas SQL
  • Finalmente veremos que los test han tenido éxito.

 

A medida que vayamos avanzando en la aplicación podremos ir

activando y desactivando los test, para que sólo se hagan test exhaustivos en

las compilaciones críticas.

Mi recomendación es que creemos módulos separados para cada

capa e intentemos que los cambios en un módulo no afecten mucho a los demás, de

manera que se hagan cada vez menos necesarios los test unitarios. Por ejemplo,

si conseguimos un modelo de datos estable, veremos reducida la necesidad de

ejecutar estas pruebas, pero si constantemente estamos modificando el modelo,

vamos a necesitar mucho tiempos para las pruebas unitarias.

Prueba de la aplicación desde un tomcat externo

Para probar la aplicación, incluyendo su war, puede ser

conveniente preparar una instalación de tomcat. Para ello basta seguir estos

pasos:

  1. Descargamos el tomcat en formato zip, por ejemplo en mi

    caso la 5.5.17 y lo descomprimimos en una carpeta, en mi caso

    D:\apps\apache-tomcat-5.5.17

  2. Creamos en nuestro espacio de trabajo la carpeta

    catalina_base y copiamos en ella las carpetas server, temp, logs y webapps

    del tomcat

  3. En nuestro espacio de trabajo creamos el siguiene fichero

    de texto

 

D:\workspace\WorkspaceCoregest\startup coregest.bat

REM script de arranque del tomcat para coregest

 

set CATALINA_BASE

D:/workspace/WorkspaceCoregest/catalina_base

 

d:

cd D:\apps\apache-tomcat-5.5.17\BIN\

STARTUP.BAT

 

  1. En nuestro espacio de trabajo nos creamos un enlace a http://localhost:8080/coregest/index.jsp

    para poder abrir el navegador rápidamente.

  2. copiamos el coregest.war de la carpeta coregest\target a

    catalina_base\webapps

 

Ahora ya podemos arrancar el tomcat rápidamente,

aprovechando el tomcat instalado en d:\apps y sin modificarlo. Así podremos

probar muchas aplicaciones diferentes con una misma instalación del tomcat.

 

Conclusión

En este tutorial hemos aprendido a integrar Hibernate en

nuestro proyecto de aplicación Web, de manera que se integra tanto con Maven

como con Eclipse. También hemos escrito el código básico de uso de Hibernate

por nuestra aplicación, así como la configuración básica del mismo. Todo esto

lo hemos probado mediante pruebas unitarias que se ejecutan automáticamente

durante la compilación del módulo de la lógica de gestión. Todo esto no es más

que el esqueleto de una aplicación, ahora nos queda mejorarlo:

  • Hayu que completar el modelo de datos de la aplicación con

    sus clases java y sus tablas en la base de datos

  • Hay que mejorar el código de soporte de Hibernate en la

    aplicación (soporte de multihilos, JNDI, etc)

  • Hay que escribir el código de los gestores de las

    entidades de nuestra aplicación. Cada gestor (manager) es responsable de

    obtener objetos de una entidad

  • También podemos integrar el EntityManager de Hibernate en

    la aplicación. Las HibernateTools nos crean unos gestores básicos que

    utilizan el EntityManager.

 

Si quereis avanzar más, podeis seguir nuestros tutoriales,

que esperamos os sean de ayuda.

Enlaces de interés

 

http://www.manning.com/bauer2/

Aquí está el capítulo 2 del libro “Java Persistence with Hibernate”

 

www.hibernate.org,

aquí están los tutoriales y manual de referencia de Hibernate

 

http://www.natidea.com/wiki/index.php?title=Hibernate_JPA

Este artículo viene con ejemplos de integración de Hibernate

 

 

 

Cristóbal González Almirón
Consultor de desarrollo de proyectos informáticos. Su experiencia profesional se ha desarrollado en empresas como Compaq, HP, Mapfre, Endesa, Repsol, Universidad Autónoma de Madrid, en las áreas de Desarrollo de Software (Orientado a Objetos), tecnologías de Internet, Técnica de Sistemas de alta disponibilidad y formación a usuarios.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad