30 agosto, 2018

1. Introducción al framework de persistencia JPA

¡Bienvenidos a todos! Esta publicación formará parte de una serie de 10 publicaciones que estaré desarrollando para aprender a crear una aplicación web en Java, bajo la plataforma JEE usando los frameworks de JPA y JSF. Este será un curso en forma de guía para todas aquellas personas que estén empezando en el mundo de la programación web.

En este curso aprenderemos a desarrollar aplicaciones web en N-CAPAS utilizando los patrones de diseño JEE, el estilo arquitectónico MVC y las funcionalidades provistas por los framework JSF (Java Server Faces) a nivel de vista-controlador y por JPA (Java Persistence API) a nivel de persistencia.

Este curso estará dividido en dos partes, En la primera parte, aprenderemos a configurar y utilizar el framework JPA mediante el desarrollo de aplicaciones Stand.Alone. En la segunda parte, aprenderemos a utilizar el framework JSF para desarrollar aplicaciones web. Por último, integraremos las funcionalidades de ambos frameworks en una aplicación final.


APLICACIÓN STAND-ALONE

Hola muchachos, en esta publicación vamos a realizar una primera aproximación al uso de JPA. Para ello vamos a implementar un aplicativo que permita realizar un CRUD a una tabla de base de datos. Aprenderemos a como realizar el ORM-Mapping para objetos y tablas relacionales, a configurar el JPA (persistence.xml) y a realizar operaciones a la base de datos. Por último, probaremos la aplicación utilizando Debug (Log4j).


OBJETIVOS

. Conocer las características y ventajas que brinda JPA.
. Conocer las consideraciones a tener en cuenta para utilizar implementaciones  de JPA.
. Desarrollar aplicaciones Java Stand-Alone que trabajen con JPA.

PASOS

1. Crear la base de datos

Paso 1:  Ejecutar el siguiente script de base de datos en el servidor MySql.
CREATE DATABASE IF NOT EXISTS mysqljpa;
USE mysqljpa;


DROP TABLE IF EXISTS tb_empleado;
CREATE TABLE tb_empleado (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  nombre varchar(45) NOT NULL,
  apellido varchar(45) NOT NULL,
  edad int(10) unsigned NOT NULL,
  area varchar(45) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


Paso 2: Crear un Proyecto JPA Stand-Alone

Vea el siguiente link para saber como crear un proyecto JPA Stand-Alone en Eclipse.

2. Realizar el ORM-Mapping (mapeo objeto-relacional)

Paso 1: Crear  el paquete “edu.aprender.persistence.entity”. 

Este paquete contendrá las clases entidad que típicamente representan a una tabla relacional de base de datos. 

Paso 2: Creación de las clases Entidad

Esta clase entidad representa una tabla relacional, por lo cual, debemos definir su METADATA; es decir, las características que la tabla presenta: nombre de la tabla, columnas, tipos de datos, llave primaria y relaciones con otras tablas. Esto se puede realizar mediante el uso de Anotaciones ó XML.

Dentro del paquete "edu.aprender.persistence.entity" crearemos la clase “Empleado.java con  las siguientes propiedades:

package edu.aprender.persistence.entity;

public class Empleado {
 
 private int id;
 private String apellido;
 private String nombre;
 private int edad;
 private String area;
 
}

Debemos de crear los métodos getters y setters ya que no debemos de olvidar que son java beans, por lo tanto, sigue las reglas de los getters y setters. Por último, sobre escribimos el método toString() para poder realizar pruebas unitarias.

Paso 3: ORM - Object Relational Mapping 

⧭ ORM es una técnica para convertir datos entre el sistema utilizado en lenguaje de POO y el utilizado en una Base de Datos Relacional. Como resultado de aplicar esta técnica, el programador podrá codificar en Java como si interactuará virtualmente con una Base de Datos Orientada a Objetos, cuya base es una Base de Datos Relacional, permitiendo así aprovechar todas las características de la programación Orientada a Objetos al interactuar con una Base de Datos Relacional.

⧭ Una instancia de una clase Entidad representará una fila de una Tabla relacional.

⧭ En el caso de JPA, tenemos 2 posibilidades de aplicar ORM

1. Utilizando el archivo de configuración orm.xml
2. Utilizando @Anotaciones

En el post nosotros aplicaremos @Anotaciones

El uso de las anotaciones requiere que se importe el paquete “javax.persistence.*” dentro de la clase Java que representa a la Entidad.

Aplicando ORM a la Clase “Empleado”.

a) Toda clase de entidad debe utilizar la anotación @Entity, la cual indica que la clase representa una tabla relacional. Añadir la anotación @Entity al inicio de la Clase Empleado.

b) Se debe utilizar la anotación @Table con el atributo name (name="Empleado"), para indicar el nombre de la tabla que la clase representa.

c) En el caso de las 5 propiedades, estas deben representar a las columnas de la tabla tb_empleado con el tipo de dato que le corresponda a cada uno, donde:

@Id: Sirve para indicar  el atributo que representa la llave primaria de la tabla.
@Column: Sirve para indicar que el atributo es una columna. 

  • Si la columna tiene el mismo nombre que el atributo, el mapeo es automático y no es necesario utilizar esta anotación.
  • Si la columna no tiene el mismo nombre, hay que utilizar la anotación @Column e indicar el nombre de la columna con el atributo name

Con estos 3 puntos hemos terminado el mapeo relacional de objeto de la tabla Empleado.


package edu.aprender.persistence.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity // @Entity: Significa que esta clase entidad representa una tabla de datos relacional
@Table(name="tb_empleado") // @Table: Es la tabla que representa esta clase entidad
public class Empleado {
 
 @Id // @id: Sirve para indicar el atributo que representa la PK de la tabla
 private int id;
 @Column(name="nombre") // @column: Sirve para indicar que el atributo es una columna, en este caso no es necesario ya que los atributos de la clase tienen el mismo nombre que las columnas de la tabla relacional
 private String nombre;
 private String apellido;
 private int edad;
 private String area;
 
 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 String getApellido() {
  return apellido;
 }
 public void setApellido(String apellido) {
  this.apellido = apellido;
 }
 public int getEdad() {
  return edad;
 }
 public void setEdad(int edad) {
  this.edad = edad;
 }
 public String getArea() {
  return area;
 }
 public void setArea(String area) {
  this.area = area;
 }
 
 // Sobreescribir el método toString para realizar pruebas unitarias
 @Override
 public String toString() {
  return "Empleado [id=" + id + ", apellido=" + apellido + ", nombre=" + nombre + ", edad=" + edad + ", area=" + area + "]";
 }
 
 /*
   Si muestra un error recuerda que tenemos que asociar la clase a una unidad de persistencia
   Las configuraciones para JPA se realizan en el archivo persistence.xml
 */

}

Si les aparece este error luego de aplicar el ORM a la clase Empleado:

Class "edu.aprender.persistence.entity.Empleado" is managed, but is not listed in the persistence.xml file o el error de la imgen



Esto es debido a que aún no hemos asociado la clase entidad a una Unidad de Persistencia, veamos el siguiente paso.

3. Configurar la unidad de persistencia

Paso 1: Definir la unidad de persistencia, el proveedor y las clases Java definidas como entidades en el archivo "persistence.xml".



Abrir el archivo "persistence.xml", nos aparecerá el editor del archivo en donde debemos seleccionar la vista "Source". Al dar clic sobre el tab “Source” veremos algo similar a esto:



Lo que haremos será agregar nuestra entidad dentro de la etiqueta "persistence-unit", guardamos y notaremos como desaparece la “X” de error en nuestra clase entidad "Empleado.java".


NOTA: El valor de RESOURCE_LOCAL indica que la conexión a la base de datos se realizará desde la misma aplicación (No empleará Pool de conexiones).


Paso 2: Crear  el paquete “edu.aprender.persistence.jpa”.


Este paquete contendrá las clases en donde se implementarán las funcionalidades de acceso a base de datos y operaciones CRUD con las tablas relacionales.

Paso 3: Crear la clase "EmpleadoJPA" 

Donde:

Método listar:

- em.getResultList(): obtiene la lista de entidades,  en base al JPQL definido

Método insertar:

- em.persist(entidadEmpleado): genera un insert a la tabla relacional mapeada con los datos del objeto.

Método actualizar:

- em.merge(entidadEmpleado): genera un update a la tabla relacional mapeada con los datos del objeto.

Método eliminar:

Para eliminar una entidad en JPA, primero debe colocarse en estado “managed”, es decir, debe cargarse al contexto de persistencia. Para ello primero debe realizarse una búsqueda.

- em.find(ClaseEntidad.class, valorLlavePrimaria): realiza una búsqueda por llave primaria en la tabla que representa la Clase Entidad. 
em.remove(entidadEmpleado): genera un delete a la tabla relacional mapeada con los datos del objeto.

IMPORTANTE: Asegúrense que los objetos entidad fueron cargados con todos los valores necesarios en sus atributos antes de ejecutar las transacciones, de lo contrario puede dar error al momento de ejecutarlas.



PASO 4: Agregar el JAR de conexión Mysql y el jar Log4j al proyecto.

Copiar las siguientes librerías al proyecto. Clic aquí para descargar:

- mysql-connector-java-5.0.8-bin.jar
- log4j-1.2.17.jar

Una vez copiado debemos de agregarlas al proyecto: selecciona las librerías, clic derecho, Build Path/Add to Build Path. De esta manera las librerías son agregadas al proyecto.



También debemos de agregar el archivo "log4j.properties" dentro de carpeta "src".



Para visualizar el log de JPA debemos de añadir al archivo "persistence.xml" la siguiente propiedad:


Paso 5: Crear una clase “Main” en el paquete "edu.aprender.test" para probar la funcionalidad.

Crear la clase “EmpleadoTest”  y añadir el siguiente código de prueba:

a) Primero inicializamos el "Persistence Manager".
b) Luego insertamos el registro con ID 1 y ejecutamos un SELECT para verificar que efectivamente fue insertado el registro.
c) Después, actualizamos el registro previamente insertado y mostramos el resultado del SELECT para verificar que todo está funcionando.
d) Luego borramos el registro con ID 1 y ejecutamos un SELECT para verificar que efectivamente fue eliminado el registro.



4. ESTRUCTURA FINAL DEL PROYECTO


Pasos para Importar y ejecutar el proyecto

1. Descargar el proyecto finalizado desde aquí
2. Revisar el proyecto en Github aquí
3. Ver como Importar un proyecto JPA Stand-Alone aquí,

NOTA:

Anteriormente en versiones como MySQL 5.7 en JPA establecíamos la conexión de la siguiente manera:

Para los que van ha utilizar la versión 8 de MYSQL, tenemos que hacer una modificación en el código anterior..

Connecting to MySQL 8.0 JPA

Client does not support authentication protocol requested by server; consider upgrading MySQL client

Para solucionar el problema realizamos los siguientes pasos:

1. Copiar el jar de conexión mysql al proyecto: "mysql-connector-java-8.0.12"
2. Agregar el jar de conexión mysql al proyecto: clic derecho "Build Path/Add to Build Path"
3. Modificar la conexión en el archivo de configuración "persistence.xml"

<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mysqljpa?useTimezone=true&amp;serverTimezone=UTC"/>


List of tz database time zones
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones


Ejemplo: Para Lima, Perú
jdbc:mysql://localhost:3306/mysqljpa?serverTimezone=America/Lima

o pueden usar la forma universal
jdbc:mysql://localhost:3306/mysqljpa?serverTimezone=UTC

No hay comentarios, ¡cuéntame algo!

Me gustaría saber tu opinión. ¡Saludos!