viernes, septiembre 22, 2006

JPA en Eclipse

En esta entrada voy a tratar de informaros sobre JPA y sobre el uso de JPA en Eclipse.

Como ya os he comentado en otra ocasión, solo voy a daros algunos apuntes básicos para luego dejaros a vuestro habitual ritmo autodidacta. Aunque por supuesto cualquier duda/problema será atendido por mi parte con mucho gusto.

Lo primero, como siempre, es saber que es JPA (Java Persistence API). JPA es la especificación del API de persistencia de EJB3.0 (http://www.jcp.org/en/jsr/detail?id=220). La especificación EJB 3.0 es muy extensa y define toda la arquitectura EJB que soporta JEE5. Una parte de este modelo es el "motor" o mecanismo de persistencia.

El objetivo del motor de persistencia es gestionar el el acceso almacenes de datos persistentes de algún tipo. Estos almacenes de datos suelen ser bases de datos relacionales aunque se pueden gestionar otros almacenes de datos como XML, etc. La razón principal para separar el acceso a datos del resto del sistema, es que de esta manera, es más sencillo reemplazar orígenes de datos y compartir objetos de acceso a datos entre aplicaciones o módulos.
Existen diferentes métodos para implementar la persistencia de datos. Es posible modelar la persistencia sin tener definido el método de implementación que puede ir desde una clase JDBC codificada manualmente, un Entity Bean (EJB) con persistencia de tipo bean-managed (BMP) o container-managed (CMP), un objeto JDO, o un objeto generado mediante una herramienta O/R (object-relational mapping tool) como TopLink o Hibernate.

La especificación JPA se introdujo en JEE5 para tratar de dar solución a este conglomerado de soluciones. Aunque como siempre, es opcional utilizarlo y es posible seguir desarrollando con las tecnologías antes citadas.

La especificación JPA se basa en la definición de objetos de tipo entidad. Normalmente una entidad se corresponde con el registro de una tabla y se define al igual que un Bean, con metodos get y set para cada uno de sus atributos (que se corresponden con el valor de cada columna de la tabla). Una vez tenemos definidos los "Entity Beans" solo necesitamos un gestor de Entidades que sea capaz de manejarlos, añadir nuevas entidades (filas), eliminarlas o modificarlas. De esta forma se independiza del motor de base de datos utilizandose un lenguaje especial para ejecutar las consultas llamado EJB QL (aunque tambien se puede utilizar SQL nativa).

Para saber en general más acerca de la especificación JPA y de como usarla debeis leer los siguientes capitulos del tutorial de JEE5:
Definición de Entidades - SUN (http://java.sun.com/javaee/5/docs/tutorial/doc/PersistenceIntro2.html)Utilización de Entidades (http://java.sun.com/javaee/5/docs/tutorial/doc/PersistenceIntro3.html)

Y como ultima referencia siempre esta el Javadoc:
Javadoc de persistencia (http://java.sun.com/javaee/5/docs/api/javax/persistence/package-summary.html)
Bien, una vez que ya sabemos que es JPA y como se utiliza ahora queremos...usarlo. Bueno, JPA es una especificación, por lo tanto hay que buscar una implementación de la misma. La implementación de referencia ofrecida por SUN es Glassfish JPA (https://glassfish.dev.java.net/javaee5/persistence/). Sin embargo, aunque es la implementación de referencia de SUN esta implementada y mantenida por ORACLE. En realidad, esta implementación se llama TopLink Essentials (http://www.oracle.com/technology/products/ias/toplink/jpa/index.html).

Para usar JPA de una forma más amigable Eclipse tiene un plugin que ayuda a crear las entidades de persistencia. Este plugin se llama Dali (http://www.eclipse.org/dali/). Basta con instalarlo adecuadamente y una vez operativo es sencillo acceder a la base de datos y generar las entidades asociadas a las tablas automaticamente. Creo que como punto de partida esta bien. Pero una vez generadas las entidades no volvemos a utilizar Dali nunca más. Así que depende y como es util o no.

Lo más coñazo de utilizar JPA es utilizar el fichero de configuración (persistence.xml). En este fichero se configura la conexión a la base de datos y demás caracteristicas necesarias para la utilización de la persistencia. Además debe residir en un sitio muy especifico (directorio META-INF en el raiz de las clases que lo utilizan).

Otra cosa que hay que explicar es que JPA se puede utilizar en aplicaciones JSE y en aplicaciones JEE. En el caso de JEE toda la configuración y gestión de los jars se deja al servidor de aplicaciones. Esto es, cada servidor de aplicaciones implementará su JPA como más le convenga (ORACLE usa TopLink, Glassfish usa TopLink Essentials, JBOSS usa Hibernate JPA, etc.). En caso de JSE es necesario mayor configuración y disponer de las librerías de implementación de JPA y del proveedor JDBC adecuado para la conexión a la base de datos.

Para empezar a trabajar con TopLink Essentials en una aplicación JSE debemos descargarnos los "jar" correspondientes y configurar adecuadamente nuestra aplicación. Este es un buen punto de partida (https://glassfish.dev.java.net/javaee5/persistence/entity-persistence-support.html).

Para empezar a jugar os recomiendo que empeceis con una aplicación JSE. Si quereis incluso puede ser una aplicación Web que podeis desplegar en el Tomcat sin necesidad de Servidor de Aplicaciones. Lo más complicado que es la configuración del fichero de configuración de la persistencia os lo paso:


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="default">
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
<!-- All persistence classes must be listed -->
<class>drm.zoo.model.AnimalEntity</class>
<properties>
<!-- Provider-specific connection properties -->
<property name="toplink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="toplink.jdbc.url" value="jdbc:oracle:thin:@maquetadb:1521:ORCL"/>
<property name="toplink.jdbc.user" value="drm"/>
<property name="toplink.jdbc.password" value="drm01"/>
<!-- Provider-specific settings -->
<property name="toplink.logging.level" value="INFO"/>
</properties>
</persistence-unit>
</persistence>

Saludos