Ejemplo de DAO genérico con JPA
Short Description
Download Ejemplo de DAO genérico con JPA...
Description
(http://sobrejava.com/)
Java SE (http://sobrejava.com/categoria/java-se)
Java EE (http://sobrejava.com/categoria/java-ee)
Ejemplo de DAO genérico con JPA
(http://sobrejava.com/autor/carlos.quijano) Spring (http://sobrejava.com/categoria/spring) JPA (http://sobrejava.com/categoria/jpa)
Oracle (http://sobrejava.com/categoria/oracle)
JSF (http://sobrejava.com/categoria/jsf)
Publicado last month Por Carlos Quijano (http://sobrejava.com/autor/carlos.quijano) Android (http://sobrejava.com/categoria/android) Otros (http://sobrejava.com/categoria/otros) Tw eet
Anuncios Google
0
19
1
► Maven Java ► Java Build ► Java Spring ► Java plugin
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/genericdao (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/), (/tag/10g/),
11g (/tag/11g/), 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…
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
4.0.0 com.sobrejava.jee generic-dao 1.0-SNAPSHOT jar GenericDAO http://www.sobrejava.com/articulos/ejemplo-de-dao-generico-con -jpa UTF-8 jpa-eclipselink org.eclipse.persistence org.eclipse.persistence.jpa 2.5.0 org.eclipse.persistence javax.persistence 2.1.0 junit junit 4.8.1 test org.apache.derby derbyclient 10.10.1.1 test
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
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 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 , 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
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 implements BaseGenericDAO { @PersistenceContext protected EntityManager em; protected Class classType; public AbstractBaseGenericDAOImpl() { super(); this.classType = (Class)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;
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
package com.sobrejava.javaee.eventos.dao; import com.sobrejava.javaee.dao.BaseGenericDAO; import com.sobrejava.javaee.eventos.model.Evento; public interface EventoDao extends BaseGenericDAO { }
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 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 org.eclipse.persistence.jpa.PersistenceProvider com.sobrejava.javaee.eventos.model.Evento
EventoDAOTest.java
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
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 jee (/tag/jee)
jpa (/tag/jpa)
Anuncios Google
eclipse-link (/tag/eclipse-link)
► Java plugin
► Java JPA
► Java IDE
► Java Jquery
★
0 comentarios
0
Deja un comentario... Mejor
Compartir
Comunidad
⤤
Nadie ha comentado aún.
r
C a n a l d e co m e n ta ri o s
✉
Su s críb e te p o r e -m a i l
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.
⚙
View more...
Comments