Ejemplo de DAO genérico con JPA

9
Anuncios Google ► Maven Java ► Java Build ► Java Spring ► Java plugin

Transcript of Ejemplo de DAO genérico con JPA

Page 1: Ejemplo de DAO genérico con JPA

(http://sobrejava.com/autor/carlos.quijano)

Publicado last month

Por Carlos Quijano (http://sobrejava.com/autor/carlos.quijano)

Tweet 0 19 1

Ejemplo de DAO genérico con JPA

Ejemplo de DAO genérico con JPA

En este ejemplo se muestra como utilizar el Patrón de DAO

(http://www.oracle.com/technetwork/java/dataaccessobject-138824.html) utilizando JPA para

crear un modelo de acceso datos genérico para la gestión de entidades de una manera

centralizada y efectiva, para ello vamos a necesitar y realizar los siguientes

Pre-requisitos

1. Java 5 o superior

2. NetBeans IDE 7 o superior

3. Esquema de Base de Datos En este ejemplo se utiliza el esquema APP de Derby el cual

ya esta integrado como servicio en NetBeans 7.

Pasos

1. Crear un proyecto utilizando NetBeans IDE y Apache Maven.

2. Crear una Interfase Base (BaseGenericDAO).

3. Crear una Implementación Abstracta (AbstractBaseGenericDAOImpl) que implemente la

interfase BaseGenericDAO.

4. Crear un DAO Concreto que extienda AbstractBaseDAOImpl para persistir una entidad

Evento.

5. Crear una Unidad de Persistencia de pruebas y su respectiva Prueba Unitaria

El código fuente del proyecto puede ser explorado en el https://github.com/carlosquijano/generic-

dao (https://github.com/carlosquijano/generic-dao) y/o descargado directamente aquí

https://github.com/carlosquijano/generic-dao/archive/master.zip

(https://github.com/carlosquijano/generic-dao/archive/master.zip).

1. Crear un nuevo Proyecto con NetBeans y Maven

En este ejemplo vamos a utilizar NetBeans 7.3 para crear un nuevo proyecto utilizando

Maven para gestionar los perfiles y dependencias del proyecto, para iniciar seleccionamos

la siguiente opción de menú

Menu > File > New Project > Maven > Java Application

Etiquetas

wlst (/tag/wlst/), weblogic

(/tag/weblogic/), web (/tag/web/), unity

(/tag/unity/), top (/tag/top/), social (/tag/social/),

sha (/tag/sha/), rmi (/tag/rmi/), referencia

(/tag/referencia/), redhat (/tag/redhat/), oracle

(/tag/oracle/), maven (/tag/maven/),login (/tag/login/), linux (/tag/linux/), libros

(/tag/libros/), juegos (/tag/juegos/), jsf (/tag/jsf/),

jrockit (/tag/jrockit/), jpa (/tag/jpa/), jee

(/tag/jee/), jdeveloper (/tag/jdeveloper/),

jdbc (/tag/jdbc/), intro (/tag/intro/), instalar

(/tag/instalar/), hash (/tag/hash/), facebook

(/tag/facebook/), exceptions (/tag/exceptions/), ejb

(/tag/ejb/), eclipse-link (/tag/eclipse-link/), config

(/tag/config/), commons (/tag/commons/),

android (/tag/android/), 11g (/tag/11g/), 10g

(/tag/10g/),

Popular

Ejemplo de DAO genérico con JPA (http://sobrejava.…

Top 5 Libros Sobre Java (http://sobrejava.com/articu…

Autenticación a Facebook Utilizando Java (http://sob…

Top 5 Librerías y Componentes JSF (http://sobrejav…

Configurar JRockit como JVM Alternativa en Oracle L…

(http://sobrejava.com/)

Java SE (http://sobrejava.com/categoria/java-se) Java EE (http://sobrejava.com/categoria/java-ee) Oracle (http://sobrejava.com/categoria/oracle)

Spring (http://sobrejava.com/categoria/spring) JPA (http://sobrejava.com/categoria/jpa) JSF (http://sobrejava.com/categoria/jsf)

Android (http://sobrejava.com/categoria/android) Otros (http://sobrejava.com/categoria/otros)

Anuncios Google ► Maven Java ► Java Build ► Java Spring ► Java plugin

Page 2: Ejemplo de DAO genérico con JPA

En la pantalla de configuración del proyecto ingresamos datos tales como nombre,

ubicación, arquetipo, grupo, versión y paquete del proyecto.

Utilizando el archivo POM vamos a importar las dependencias necesarias en un perfil que

nos permita "cambiar" de implementaciones en algún momento dado, en este ejemplo

vamos a utilizar JPA 2.1 con Eclipse Link 2.5, jUnit 4 y Apache Derby respectivamente,

para ello utilizaremos un POM como el siguiente

pom.xml

Page 3: Ejemplo de DAO genérico con JPA

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://ww

w.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apac

he.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.sobrejava.jee</groupId>

<artifactId>generic-dao</artifactId>

<version>1.0-SNAPSHOT</version>

<packaging>jar</packaging>

<name>GenericDAO</name>

<url>http://www.sobrejava.com/articulos/ejemplo-de-dao-generico-con

-jpa</url>

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncodi

ng>

</properties>

<profiles>

<profile>

<id>jpa-eclipselink</id>

<dependencies>

<dependency>

<groupId>org.eclipse.persistence</groupId>

<artifactId>org.eclipse.persistence.jpa</artifactId

>

<version>2.5.0</version>

</dependency>

<dependency>

<groupId>org.eclipse.persistence</groupId>

<artifactId>javax.persistence</artifactId>

<version>2.1.0</version>

</dependency>

</dependencies>

</profile>

</profiles>

<dependencies>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.8.1</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.apache.derby</groupId>

<artifactId>derbyclient</artifactId>

<version>10.10.1.1</version>

<scope>test</scope>

</dependency>

</dependencies>

</project>

Notar que el POM hace uso de perfiles, es decir, que las depedencias serán

descargadas/utilizadas según el perfil. Es posible crear otro perfil que utilize

Hibernate por ejemplo.

Ahora informamos a NetBeans IDE que utilize el perfil jpa-eclipselink , para ello es

necesario seleccionarlo del menu contextual Set Configuration del proyecto (Click Derecho)

Menu Contextual Proyecto > Set Configuration > jpa-eclipselink

Page 4: Ejemplo de DAO genérico con JPA

2. Interfase Base

Una vez configurado el proyecto, iniciaremos el desarrollo de la interfase BaseGenericDAO

la cual se utilizara genéricamente para las operaciones CRUD (Create, Update, Delete) de

las entidades a persistir con JPA.

BaseGenericDAO.java

package com.sobrejava.javaee.dao;

import java.io.Serializable;

public interface BaseGenericDAO<T, K extends Serializable> {

T create(T entity);

T update(T entity);

void delete(T entity);

T findById(K key);

}

Notar que la interfase hace uso de tipos genéricos <T, K>, donde "T" representa

la entidad a persistir y "K" el tipo de la llave primaria de la entidad. De esta

manera se "generaliza" el uso de la interfase para casi cualquier entidad.

3. Implementación Abstracta

Tomando en cuenta que BaseDAO es una interfase y que debe de ser implementada para

darle funcionalidad, creamos una nueva clase abstracta AbstractBaseGenericDAOImpl que

implemente los métodos definidos en BaseDAO utilizando JPA como motor de

persistencia.

AbstractBaseGenericDAOImpl.java

Page 5: Ejemplo de DAO genérico con JPA

package com.sobrejava.javaee.dao.jpa;

import com.sobrejava.javaee.dao.BaseGenericDAO;

import java.io.Serializable;

import java.lang.reflect.ParameterizedType;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

public abstract class AbstractBaseGenericDAOImpl<T, K extends Serializa

ble> implements BaseGenericDAO<T, K> {

@PersistenceContext

protected EntityManager em;

protected Class<T> classType;

public AbstractBaseGenericDAOImpl() {

super();

this.classType = (Class<T>)getParameterClass(getClass(), 0);

}

@Override

public T create(T entity) {

this.em.persist(entity);

return entity;

}

@Override

public T update(T entity) {

return this.em.merge(entity);

}

@Override

public void delete(T entity) {

this.em.remove(entity);

}

@Override

public T findById(K key) {

return this.em.find(classType, key);

}

private static Class<?> getParameterClass(Class<?> clazz, int index

) {

return (Class<?>)(((ParameterizedType)clazz.getGenericSuperclas

s()).getActualTypeArguments()[index]);

}

}

Lo único especial a notar en la clase AbstractBaseGenericDAOImpl es el uso

del método privado getParameterClass el cual se utiliza para obtener el tipo de

objeto de la clase parametrizada K.

4. DAO Concreto

Una vez definida la clase abstracta AbstractBaseGenericDAOImpl es necesario extenderla

en un DAO Concreto es decir en un DAO con sentido ya orientado a una entidad en

específico, en este ejemplo, vamos a crear un DAO que persista una entidad Evento la

cual es la representación de una tabla APP.EVENTS en el esquema APP del Derby

integrado de NetBeans.

Evento.java

package com.sobrejava.javaee.eventos.model;

import java.io.Serializable;

import java.sql.Timestamp;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

Page 6: Ejemplo de DAO genérico con JPA

import javax.persistence.Id;

import javax.persistence.Table;

@Entity

@Table(name = "EVENTS")

public class Evento implements Serializable {

public static final String SEVERIDAD_INFO = "INFO";

public static final String SEVERIDAD_ERROR = "ERROR";

public static final String SEVERIDAD_DEBUG = "DEBUG";

public static final String SEVERIDAD_FATAL = "FATAL";

@Id

@Column(name = "EVENT_ID")

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long eventoId;

@Column(name = "SEVERITY", length = 32)

private String severidad;

@Column(name = "MESSAGE", length = 512)

private String mensaje;

@Column(name = "STAMP")

private Timestamp fecha;

public Long getEventoId() {

return eventoId;

}

public void setEventoId(Long eventoId) {

this.eventoId = eventoId;

}

public String getSeveridad() {

return severidad;

}

public void setSeveridad(String severidad) {

this.severidad = severidad;

}

public String getMensaje() {

return mensaje;

}

public void setMensaje(String mensaje) {

this.mensaje = mensaje;

}

public Timestamp getFecha() {

return fecha;

}

public void setFecha(Timestamp fecha) {

this.fecha = fecha;

}

}

EventoDAO.java

Page 7: Ejemplo de DAO genérico con JPA

package com.sobrejava.javaee.eventos.dao;

import com.sobrejava.javaee.dao.BaseGenericDAO;

import com.sobrejava.javaee.eventos.model.Evento;

public interface EventoDao extends BaseGenericDAO<Evento, Long> {

}

EventoDAOImpl.java

package com.sobrejava.javaee.eventos.dao.jpa;

import com.sobrejava.javaee.dao.jpa.AbstractBaseGenericDAOImpl;

import com.sobrejava.javaee.eventos.dao.EventoDao;

import com.sobrejava.javaee.eventos.model.Evento;

public class EventoDaoImpl extends AbstractBaseGenericDAOImpl<Evento, L

ong> implements EventoDao {

}

Notar que la interfase EventoDAO extiende a BaseGenericDAO tipificandola con

la entidad Evento y Long, es decir, es un DAO concreto para la entidad Evento

y su llave primaria del tipo Long. Asimismo la implementación JPA de dicha

interfase EventoDAOImpl extiende a AbstractBaseGenericDAOImpl la cual

hereda su funcionalidad.

5. Unidad de Persistencia y Prueba Unitaria

Finalmente vamos a crear una unidad de persistencia (Persistence Unit) de pruebas y una

prueba unitaria con jUnit para probar el EventoDAO.

META-INF/persistence.xml

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persisten

ce" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLoc

ation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml

/ns/persistence/persistence_2_1.xsd">

<persistence-unit name="pu-generic-dao-test" transaction-type="RESOUR

CE_LOCAL">

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider

>

<class>com.sobrejava.javaee.eventos.model.Evento</class>

<properties>

<property name="javax.persistence.jdbc.url" value="jdbc:derby://l

ocalhost:1527/sample"/>

<property name="javax.persistence.jdbc.password" value="app"/>

<property name="javax.persistence.jdbc.driver" value="org.apache.

derby.jdbc.ClientDriver"/>

<property name="javax.persistence.jdbc.user" value="app"/>

<property name="eclipselink.ddl-generation" value="create-tables"

/>

</properties>

</persistence-unit>

</persistence>

EventoDAOTest.java

Page 8: Ejemplo de DAO genérico con JPA

package com.sobrejava.dao;

import com.sobrejava.javaee.eventos.model.Evento;

import java.sql.Timestamp;

import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;

import javax.persistence.EntityTransaction;

import javax.persistence.Persistence;

import org.junit.After;

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

public class EventoDaoTest {

String pu = "pu-generic-dao-test";

EntityManager em;

EntityManagerFactory emf;

@Before

public void before() {

this.emf = Persistence.createEntityManagerFactory(pu);

this.em = emf.createEntityManager();

}

@Test

public void testSaveEvents() {

Assert.assertNotNull(em);

Timestamp stamp;

EntityTransaction trx = null;

try {

trx = em.getTransaction();

stamp = new Timestamp(System.currentTimeMillis());

Evento evento = new Evento();

evento.setFecha(stamp);

evento.setMensaje("Este es un mensaje generado en " + stamp

);

evento.setSeveridad(Evento.SEVERIDAD_INFO);

trx.begin();

em.persist(evento);

trx.commit();

} catch (RuntimeException e) {

if (trx != null && trx.isActive()) {

trx.rollback();

}

}

}

@After

public void after() {

em.close();

emf.close();

}

}

Notar que es antes de ejecutar la prueba unitaria es necesario iniciar la base

de datos

Al ejecutar la prueba unitaria, de no existir problemas se puede observar algo similar a lo

siguiente:

APP.EVENTS

Page 9: Ejemplo de DAO genérico con JPA

jee (/tag/jee) jpa (/tag/jpa) eclipse-link (/tag/eclipse-link)

Conclusiones

Con la estrategia anterior es posible generar un DAO para cada entidad, prácticamente copiando

y pegando las 3 clases anteriores (Evento, EventoDAO, EventoDAOImpl) y aunque exista cierto

grado de trabajo, el nivel de flexibilidad que se obtiene es de gran escala, ya que podemos

extender e implementar más métodos tales como count, findAll, findBy, etc. utilizando las

mismas clases dependiendo de la necesidad de una manera simple, elegante y fácil de entender.

Referencias

1. Core J2EE Patterns - Data Access Object

http://www.oracle.com/technetwork/java/dataaccessobject-138824.html

(http://www.oracle.com/technetwork/java/dataaccessobject-138824.html)

Tags

0 comentarios

Deja un comentario...

Mejor Comunidad ⚙ ⤤Compartir

Nadie ha comentado aún.

Canal de com entariosr Sus críbete por e-m ai l✉

0★

Inicio (http://sobrejava.com/) · Acerca de (http://sobrejava.com/acerca-de) · Contacto

(http://sobrejava.com/contacto)

Copyright © 2013 SobreJava.com. Carlos Quijano. Todos los derechos reservados.

Marcas Registradas como Java y Oracle son propiedad de Oracle Corportation y/o sus respectivos

propietarios intelectuales.

Anuncios Google ► Java plugin ► Java JPA ► Java IDE ► Java Jquery