HolaMundoJPA o persistencia con JPA, Eclipselink y Derby

En esta ocasión voy a desarrollar un ejemplo muy básico de persistencia. La idea es hacer una aplicación minúscula que nos haga persistir un objeto. Un holaMundoJPA con únicamente cuatro archivos. La entidad a persistir, el archivo pom que nos gestiona librerias y ciclo de vida, la configuración de jpa y el método main.

Atacaré una ApacheDerby/JavaDB que viene por defecto incluida con la instalacion del jdk1.6. Apache derby puede trabajar en modo embebido o en modo servidor. En el ejemplo utilizaré el modo servidor que es normalmente la forma más normal de trabajar con bbdd, si bien para aplicaciones de escritorio o test puede ser más interesante trabajar con ella en modo embebido.

Como siempre las herramientas empleadas son Eclipse, esta vez Indigo, jdk 1.6 y maven  y Derby

Primero vamos a arrancar Derby, para lo cual lanzaremos el bat:

C:\Archivos de programa\Sun\JavaDB\bin\startNetworkServer.bat

Lo cual nos debería dar una salida de consola como esta:
2013-04-06 09:28:28.987 GMT : Se ha instalado el administrador de seguridad utilizando la directiva de seguridad de servidores básica.
2013-04-06 09:28:31.112 GMT : Apache Derby Network Server - 10.6.2.1 - (999685) se ha iniciado y está listo para aceptar conexiones en el puerto 1527


Empezaremos por las librerias necesarias, Necesitamos  JPA, el provider Eclipselink y el driver de conexión con la bbdd de Derby Voy a utilizar eclipselink como provider y necesito añadir su repositorio.
El cuerpo del pom.xml quedará como sigue:
    <dependencies>
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>javax.persistence</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
            <version>10.6.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbyclient</artifactId>
            <version>10.6.1.0</version>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>EclipseLink Repo</id>
            <url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
        </repository>
    </repositories>
    <build>
        <finalName>jpauno</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>


Es dificil crear una capa de persistencia con menos librerias.

En la carpeta src/main/resources META-INF debemos introducir el archivo "persistence.xml" en el cual definimos la unidad de persistencia:

?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="unjpa" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>prueba.persis.unjpa.bean.Usuario</class>

        <properties>
             <property name="eclipselink.target-database" value="DERBY" />
            <property name="eclipselink.ddl-generation" value="create-tables" />
            <property name="eclipselink.logging.level" value="INFO" />
            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
            <property name="javax.persistence.jdbc.url"
                value="jdbc:derby://localhost:1527/taller;create=true" />
            <property name="javax.persistence.jdbc.user" value="taller" />
            <property name="javax.persistence.jdbc.password" value="taller" />
        </properties>
    </persistence-unit>
</persistence>


Creo que se intuye bastante bien qué hace cada propiedad. El logging level está a "info" y uno puede estar tentado de pasarlo a debug, pero no, en jpa se utiliza java.util.logging y no log4j y por tanto los niveles no son debug, info, warn sino que son fine, info, severe. Destacar que le hemos indicado que se encargue el mismo de generar las tablas. Siéntete libre de investigar que otras opciones hay además de "create-tables".

Documentación de EclipseLink.

Veamos el objeto a persistir

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity ()
public class Usuario implements Serializable {

    private static final long serialVersionUID = 1L;
   
    @Id @GeneratedValue
    private int userId;
   
    @Column (length=45)
    private String name;
    @Column (length=45)
    private String surname;
    @Column (length=8)
    private String password;

.....
//getters y setters

Definimos una entidad con cuatro campos, el primero como clave primaria etiquetado como @Id y le indicamos que el propio SGBD se encargue de generar el valor @GeneratedValue. La entidad es un javabean con un constructor sin parámetros.

Y por último creamos el  main.

 public static void main( String[] args )
    {
        Usuario newUser= new Usuario();
        newUser.setName("Andrés");
        newUser.setSurname("Gaudioso");
        newUser.setPassword("secreto");
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("unjpa");
        EntityManager em= emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.persist(newUser);   
        tx.commit();
        System.out.println("Objeto persistido " + newUser + " con identificador " + newUser.getUserId());
    }


Destacar que el Persistence.createEntityManagerFactory("unjpa") hace referencia a la unidad de persistencia que hemos creado indicado en "persistence.xml". La primera vez que lo ejecutemos todo funcionará correctamente, pero la segunda nos indicará que no puede crear la tabla porque esta exist. Si comentas la siguiente linea del persistence.xml
   <property name="eclipselink.ddl-generation" value="create-tables" />
solucionas el problema. Insisto en que investigues que otras opciones existen.
En cualquiera de los casos la salida debería ser algo según esto:

    System.out.println("Objeto persistido " + newUser.getName()
                + " con identificador " + newUser.getUserId());

>> Objeto persistido Andrés con identificador 151

Para ejecutarlo desde el eclipse. Desde run configurations como Maven Build con el proyecto seleccionado ejecuto el Goal
clean compile exec:java -Dexec.mainClass="prueba.persis.unjpa.App"

que es la forma de indicarle dónde está el main. Y no te olvides de arrancar la BBDD antes de probarlo.

El proyecto completo puedes descargártelo aquí