Mostrando las entradas con la etiqueta Introducción a JPA. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Introducción a JPA. Mostrar todas las entradas

09 abril, 2020

Crear un proyecto JPA Stand Alone usando Hibernate en Eclipse (Maven)

En este post aprenderemos a crear un proyecto JPA Stand Alone usando Hibernate como implementación de JPA y Maven, que es una herramienta de software para la gestión y construcción de proyectos.

¿Qué es JPA?

Java Persistence API es una especificación de persistencia para la plataforma JAVA que aplica el Mapeo Relacional Objeto  (ORM: Object-Relational Mapping) permitiendo interactuar con bases de datos relacionales sin perder las ventajas de la orientación a objetos. Esto permite construir  aplicaciones  completamente orientadas a objetos. Algunas de las implementaciones mas conocidas de JPA son: Hibernate, TopLink, OpenJPA, EclipseLink.

¿Qué es Hibernate?

Hibernate es una herramienta de mapeo objeto-relacional (ORM) para Java, que facilita el mapeo de atributos en una base de datos tradicional, y el modelo de objetos de un aplicación mediante archivos declarativos o anotaciones en los beans de las entidades que permiten establecer estas relaciones.

¿Qué es Maven?

Normalmente cuando trabajamos con Java/JavaEE el uso de librerías es algo común como en cualquier otro lenguaje de programación. Sin embargo, una librería puede depender de otras librerías para funcionar de forma correcta. Por ende, su gestión se puede volver tedioso a la hora de buscar las librerías y ver que versión exacta debemos de elegir. Así pues necesitamos más información para gestionarlo todo de forma correcta  y para ellos existe MAVEN, que es una herramienta que nos va a permitir tener una gestión correcta de nuestra librerías, proyectos y dependencias. Dentro de un proyecto Maven el archivo pom.xml (Proyect Object Model) es el de mayor importancia ya que contiene toda la información del artefacto que usará nuestro proyecto. Un Artefacto puede verse como una librería con esteroides (aunque agrupa mas conceptos). Contiene las clases propias de la librería pero ademas incluye toda la información necesaria para su correcta gestión (grupo, versión, dependencias etc).

PASOS

1. Crear la base de datos

Abrir el MySQL Workbench y ejecutar el siguiente script:


2. Crear un Maven Project

Clic en File/New/Maven Project.


 Seleccionamos el arquetipo "maven-archetypes-webapp" de "org.apache.maven.archetypes".



Group Id: identifica de forma exclusiva su proyecto en todos los proyectos. Una ID de grupo debe seguir las reglas de nombre de paquete de Java . Esto significa que comienza con un nombre de dominio invertido que controlas. Por ejemplo, org.apache.maven, org.apache.commons.

Artifact Id: es el nombre del jar sin versión. Si lo creó, puede elegir el nombre que desee con letras minúsculas y sin símbolos extraños. Si se trata de un jar de un tercero, debe tomar el nombre del jar tal como está distribuido.

Versión: si distribuye, entonces usted puede elegir cualquier versión típica con números y puntos (1.0, 1.1, 1.0.1, ...). No use fechas, ya que generalmente están asociadas con compilaciones SNAPSHOT (todas las noches). Si se trata de un artefacto de un tercero, debe usar su número de versión, sea lo que sea, y por extraño que parezca. Por ejemplo, 2.0, 2.0.1, 1.3.1.


Clic en "Finish" y tendremos la siguiente estructura


El error que no muestra va a desaparecer cuando agreguemos las dependencias.

3. Agregar las dependencias para este proyecto

Abrimos el archivo "pom.xml" y agregamos las siguientes dependencias:

javax.servlet-api: para trabajar con serlvets (hace que desaparezca el error anterior).
mysql-connector-java: driver de conexión mysql.
hibernate-core: para trabajar con hibernate.



No olvidemos que tenemos que cambiar la versión de Java de 1.7 a 1.8.

Guardamos los cambios y podemos observar que dentro del directorio Maven Dependencies se han descargados todas las librerías. Si no les descarga las librerías de manera automática, debemos hacer clic derecho al proyecto y seleccionar la opción Maven/Update Project...


4 Aparecer directorio ocultos de Java

Clic derecho al proyecto y seleccionamos la opción /Build Path/Configure Build Path...
En la venta que se abre marcamos la casilla Maven Dependencies y hacemos clic en Aplicar.


Como podemos observar, aparecieron directorios que estaban ocultos.


5. Crear el archivo persistence.xml

Clic derecho al proyecto y seleccionamos la opción New/Folder.

Dentro del proyecto seleccionamos la ubicación src/main/java y creamos el folder llamado META-INF


Ahora damos clic derecho en la carpeta META-INF y seleccionamos la opción  New/Other/XML File. 


Dentro de esta carpeta crearemos el archivo persistence.xml y copiamos el siguiente código.



El código "?useTimezone=true&serverTimezone=UTC" es adicional. Si no colocaba esta instrucción me iba a saltar el error "Client does not support authentication protocol requested by server; consider upgrading MySQL client".

6. Crear el modelo

Crear la clase Producto.java dentro del paquete com.aprendec.model.

⧭ 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”.

@Entity: Significa que esta clase entidad representa una tabla de datos relacional
@Table: es la tabla que representa esta clase entidad.
@id: sirve para indicar el atributo que representa la PK de la tabla.
@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.



7. Invocar a la unidad de persistencia

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

Crear la clase JPAUtil.java dentro del paquete com.aprendec.app para que haga el llamado a la unidad de persistencia definida en el archivo persistence.xml, de tal manera que podamos instanciar a este archivo y podamos tener contacto con la base de datos.

Crear la clase MainApp.java dentro del paquete com.aprendec.app para crear las operaciones CRUD.


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.


8, Probar aplicación


9. Estructura final del proyecto


Descargar proyecto

17 septiembre, 2018

3. Relaciones entre entidades

¡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

Continuando con el post anterior donde aprendimos a crear una clase EntityListener para monitorear el ciclo de vida de una entidad. Hoy aprenderemos a relacionar entidades según el modelo de datos.

OBJETIVOS

. Creación de nuevas entidades (Cargo y Casillero)
. Configuración ORM y relaciones entre entidades según el modelo de datos
. Mapeo lógico con (@OneToMany, @ManyToOne, @OneToOne)
. Mapeo físico con (@JoinColumn)

APLICACIÓN

1. Ejecutar el proyecto de la sesión anterior

Vamos a crear una copia del proyecto de la sesión anterior y le cambiaremos el nombre a "Aplicacion_JPA_03".


Después de importar nuestro proyecto compilamos el archivo "script2 y script3" que se encuentra dentro de la carpeta "bd". Asimismo, es opcional cambiar el nombre a la unidad de persistencia en el archivo "persistence.xml" y también la referencia a ella en el método "setup" de la clase "EmpleadoJPA", las cuales tienen el nombre del proyecto anterior "Aplicacion_JPA_02". Ustedes pueden ponerle el nombre que deseen a su unidad de persistencia, yo le pondré "Aplicacion_JPA_03" para que vaya acorde con el nombre del proyecto.

persistence.xml...
<persistence-unit name="Aplicacion_JPA_03">" 

EmpleadoJPA
"emf =Persistence.createEntityManagerFactory("Aplicacion_JPA_03");"  

Ver como importar un proyecto JPA aquí

El proyecto debe tener la siguiente estructura.


2. ORM y Anotaciones 

Vamos a realizar nuevas configuraciones al proyecto 

Paso 1: Crear las entidades Cargo y Casillero

Clase Empleado:

Añadir el nuevo campo “Fecha de Ingreso” a la clase "Empleado".


Por ser "java.sql.Date", no requiere uso de anotación "@Temporal".

Añadir la siguiente línea de código en "EmpleadoTest".


Clase Cargo:


Clase Casillero:


Paso 2:  Registrar las nuevas entidades en el archivo "persistence.xml"


Paso 3: Configurar ORM de Relaciones entre entidades según el modelo de Datos

Según el modelo lógico, la clase "Cargo" tiene relación con la clase "Empleado", por lo cual dependiendo de la navegabilidad definida en el diagrama de clases, se deberá representar dicha relación en una ó ambas clases relacionadas. En este caso como la  navegabilidad es bidireccional, tenemos que representar la relación en ambas clases, basándonos en las multiplicidades definidas. En el gráfico, leer relación desde clase origen a clase destino. 



Por ejemplo si origen = Cargo y destino = Empleado entonces se lee: 

“Un Cargo lo pueden tener uno o muchos Empleados”. → OneToMany

Por ejemplo si origen = Empleado y destino = Cargo entonces se lee: 
“Uno o Muchos Empleados pueden tener un mismo Cargo”. → ManyToOne

Relación ManyToOne
Se utiliza cuando la multiplicidad hacia la clase relacionada es 1.

Relación OneToMany

Se utiliza cuando la multiplicidad hacia la clase relacionada es  de 0(1) a muchos.

Debemos añadir los campos que representan las relaciones según navegabilidad y multiplicidad.

Clase Empleado:

No olvidar generar "getter/setter" y redefinir el método "toString()".

Clase Cargo:

No olvidar generar "getter/setter" y redefinir el método" toString()".

Clase Casillero:

No olvidar generar "getter/setter" y redefinir el método "toString()".

Paso 4: Inicializar los objetos para realizar pruebas



Paso 5: Probar Aplicación


ESTRUCTURA FINAL DEL PROYECTO



NOTA: 

No olvidemos que tenemos que crear las tablas "tb_cargo" y "tb_casillero" con sus registros y agregar la columna "FEC_ING_EMP" a la tabla "tb_empleado" en nuestra base de datos.

Pasos para Importar y ejecutar el proyecto

1. Descargar el proyecto finalizado desde aquí
2. Revisar proyecto en Github aquí
3. Ver como importar un proyecto JPA aquí


31 agosto, 2018

2. Gestión de la capa de persistencia

¡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


Continuando con el post anterior donde vimos una primera aproximación al uso de JPA implementando un proyecto Stand-Alone que permita realizar un CRUD a una tabla determinada. Hoy, aprenderemos a crear una clase EntityListener para monitorear el ciclo de vida de una entidad.

OBJETIVOS

. Definimos un EntityListener para comprender el Ciclo de Vida de una Entidad.
. Definimos más anotaciones (@Basic, @Column, @Transient).
. Definimos estrategias de generación de llave primaria usando (Identity, table, AUTO).

PASOS

1. Ejecutar el proyecto del post anterior

Paso 1: Importar el proyecto del post anterior

Vamos a crear una copia del proyecto de la sesión anterior y le cambiaremos el nombre a "Aplicacion_JPA_02".


Después de importar nuestro proyecto, ejecutamos el archivo "script1" que se encuentra dentro de la carpeta "bd". Asimismo, es opcional cambiar el nombre a la unidad de persistencia en el archivo "persistence.xml" y también la referencia a ella en el método "setup" de la clase "EmpleadoJPA", las cuales tienen el nombre del proyecto anterior "Aplicacion_JPA_01". Ustedes pueden ponerle el nombre que deseen a su unidad de persistencia, yo le pondré "Aplicacion_JPA_02" para que vaya acorde con el nombre del proyecto.

persistence.xml...

<persistence-unit name="Aplicacion_JPA_02">" 

EmpleadoJPA

"emf =Persistence.createEntityManagerFactory("Aplicacion_JPA_02");"  

Ver como importar un proyecto JPA aquí.

El proyecto debe tener la siguiente estructura:


Seleccionamos la clase "EmpleadoTest", clic derecho al archivo, Run As/Java Application para ejecutar la aplicación.



Hasta aquí es lo que hemos visto en el post anterior.

2. Comprendiendo el Ciclo de Vida de una Entidad

Paso 1: Creación del Entity Listener

Dentro del paquete "edu.aprender.persistence.entity.listener" creamos la clase “EmpleadoListener.java” con  las siguientes propiedades:



Paso 2: Uso del EntityListener 

Utilizando anotaciones en la entidad “Empleado.java”.

a) Para asociar un Entity Listener a una Entidad se debe utilizar la anotación @EntityListeners la cual indica la clase que implementa los métodos “callbacks” gestionados por anotaciones como @PrePersist.

En la clase "Empleado.java" añadir la línea de código resaltada:


Paso 3: Probar aplicación


Nos dirigimos a la clase "EmpleadoTest", clic derecho, /Run As/Java Application para ejecutar la aplicación.


3. ORM y Anotaciones 

Paso 1: Anotacions @Basic, @Column, @Transient


La anotación @Basic (que es opcional) se utiliza para indicar de forma explícita que dicho atributo debe ser almacenado en la base de datos. Por defecto, todas los atributos de una Entidad tienen asignada dicha anotación.

La anotación @Column (que es opcional) se utiliza para indicar las características físicas de la columna en la tabla de base de datos. Es necesario su uso por ejemplo cuando el nombre de la columna de la tabla de base de datos es distinto al del atributo definido en la Entidad.

Ejemplo:

Vamos a ejecutar este "script2" donde se ha modificado los nombre de las columnas:

Añadir anotaciones en la entidad “Empleado”, según lo resaltado y definir sus métodos de acceso getters and setters.

La anotación @Transient (que es opcional) se utiliza para indicar aquellos atributos que no forman parte de ninguna tabla relacional. Atributos cuyo valor se genera en tiempo de ejecución para realizar alguna funcionalidad, pero cuyo valor no necesita ser persistente.

Entonces la entidad "Empleado" quedaría de la siguiente manera:

Por ejemplo: 

a) Añadir a la entidad "Empleado" el atributo “nombreCompleto” 
b) Generar "getter/setter" y redefinir el método "toString()" 
c) Probamos la aplicación


4. Manejo de Llave Primaria 

Paso 1: @GenerateValue 

Vamos a definir una estrategia de generación de llave Primaria 

Estrategia 1 usando "IDENTITY"

Añadir en la entidad "Empleado" lo resaltado:
@Id
@Column(name="COD_EMP",unique=true,nullable=false) 
@GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;

En la clase "EmpleadoTest" comentar la línea resaltada y volver a Probar:
public static void main(String[] args) {
   EmpleadoJPA empleadoJPA = new EmpleadoJPA();
   empleadoJPA.setup();
  
   // Entidad con datos estáticos
   Empleado entidadEmpleado = new Empleado();
   //entidadEmpleado.setId(1);
   entidadEmpleado.setNombre("Antonio");
   entidadEmpleado.setApellido("Perez");
   entidadEmpleado.setEdad(30);
   entidadEmpleado.setArea("Sistemas");

Revisar en el log el código autogenerado

Estrategia 2 usando "TABLE"

Crear una tabla adicional en la base de datos de ejemplo, según el "script3":
use mysqljpa;

DROP TABLE IF EXISTS tb_secuencia;
CREATE TABLE tb_secuencia(
  descripcion varchar(10) NOT NULL,
  valor int(10) NOT NULL,
  PRIMARY KEY (descripcion)
);

insert into tb_secuencia values('empleado',0);

En la entidad "Empleado" añadir el código resaltado:

@Id
@Column(name="COD_EMP",unique=true,nullable=false)
@GeneratedValue(strategy= GenerationType.TABLE, generator="generador")
@TableGenerator(name="generador", table="tb_secuencia", pkColumnName="descripcion",valueColumnName="valor", pkColumnValue="empleado", allocationSize=1)
private int id;

Probar aplicación y revisar en el log el código autogenerado

Estrategia 3 usando "AUTO"

En la entidad "Empleado" actualizar según el código resaltado:
@Id
@Column(name="COD_EMP",unique=true,nullable=false)
@GeneratedValue(strategy= GenerationType.AUTO, generator="generador")
@TableGenerator(name="generador", table="tb_secuencia", pkColumnName="descripcion",valueColumnName="valor", pkColumnValue="empleado", allocationSize=1)
private int id;

En el caso de Mysql, la estrategia "AUTO" selecciona como mejor opción obtener el código de la tabla “sequence”, en caso de tener una tabla con nombre distinto pero con las mismas características, hay que indicar un "TableGenerator", tal cual se ve en el ejemplo.

Probar la aplicación y revisar el log el código autogenerado.

La clase entidad Empleado.java

ESTRUCTURA FINAL DEL PROYECTO


Pasos para Importar y ejecutar el proyecto

1. Descargar el proyecto finalizado desde aquí
2. Ver proyecto en Github aquí
3. Ver como importar un proyecto JPA aquí

Conectando a MySQL 8.0 desde un JPA Proyect

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


Nota: 

1. Deben tener agregado el jar de conexión MYSQL "mysql-connector-java-8.0.x" a su proyecto.
2. Deben agregar la zona horaria de la base de datos, déjenlo en UTC por defecto o si desean especificar su ciudad, les dejo estas lista con los nombres: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones