Imprimir

Contenidos anteriores de este tutorial:

Conexión con la base de datos desde Java

Código de conexión con la base de datos

La conexión con una base de datos usando JPA se realiza utilizando un objeto de la clase EntityManagerFactory que puede ser obtenido a partir de la llamada al método Persistence.createEntityManagerFactory al que se le indicará por parámetro el nombre de la unidad de persistencia que contiene los datos de conexión (en este caso era AgendaContactosPU, como vimos anteriormente en el archivo persistence.xml).

A partir de ese objeto se podrá crear otro de la clase EntityManager que será el que se utilice posteriormente para realizar las operaciones con la base datos.

Por tanto, para realizar la conexión a la base de datos se deberá indicar un código como el siguiente:

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class AgendaContactos {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("AgendaContactosPU"); // Comprobar nombre de la PU
        EntityManager em = emf.createEntityManager();
    }

}

Conviene probar el código anterior para ver que se realiza correctamente la conexión a la base de datos desde Java. En caso de que se produzca un error deberías comprobar que no haya ninguna otra conexión activada con la misma base de datos (ten en cuenta que en este tutorial no se está usando un servidor de base de datos como MySQL, por lo que sólo puede haber una conexión activa). Esto podría ocurrir si no se ha desconectado la conexión que se hizo en una parte anterior de este tutorial. Comprueba el estado de esa conexión en la pestaña Services y realiza la desconexión si está activada.

Captura de pantalla de 2017 04 17 13 47 24 d840e

Añadir librerías del driver del gestor de base de datos

Una vez que se tenga escrito ese código, si se intenta ejecutar se obtendrá el siguiente error: Configuration error.  Class [org.apache.derby.jdbc.EmbeddedDriver] not found. Este error es debido a que no se ha añadido la librería de Java DB al proyecto, ya que esta aplicación se desea conectar a una base de datos de ese tipo. Si se quisiera conectar a una base de datos MySQL, habría que añadir la librería correspondiente de MySQL. Para la utilización de JPA también es necesaria la librería de EclipseLink, pero esa se habrá añadido automáticamente al proyecto al utilizar el asistente para crear las clases entidad.

Captura de pantalla 2018 05 09 a las 11.10.22 cb1b3

Puedes añadir las librerías necesarias desde el menú contextual de la carpeta Libraries, seleccionando la opción Add Library.

Screen Shot 2017 04 05 at 21.35.00 320f0

 Elige la librería correspondiente al tipo de base de datos. En este caso, Java DB Driver.

Screen Shot 2017 04 05 at 21.36.08 9580e

 La carpeta Libraries debería quedar ahora así:

Screen Shot 2017 04 05 at 21.37.49 c4e46 

Y ya se podrá ejecutar sin problemas el código de conexión con la base de datos. 

Crear tablas automáticamente

Esta conexión ha tomado por defecto la configuración de la unidad de persistencia que se ha especificado (AgendaContactosPU), pero en muchos casos puede ser conveniente ajustar alguno de los parámetros de esa configuración. Por ejemplo, si ahora mismo se intentara hacer alguna operación sobre una de las tablas de la base de datos, obtendríamos un error, ya la base de datos se habrá creado al hacer la conexión anterior, pero las tablas que debe contener no se habrán creado. Resulta conveniente, por tanto, que se indique en la unidad de persistencia, que las tablas deben crearse automáticamente si no existieran.

Esto puede hacer desde la configuración del archivo persistence.xml, o bien añadiendo algunas propiedades desde el código fuente.

Si se prefiere hacer desde el archivo persistence.xml, tan sólo hay que marcar la opción Create del apartado Table Generation Strategy.

Screen Shot 2017 04 05 at 21.32.58 3957c

Esa acción se encarga de añadir en el código XML de ese archivo la línea siguiente:

<property name="javax.persistence.schema-generation.database.action" value="create"/>

Si se prefiere hacer desde el código fuente de la aplicación, y así tener oportunidad de cambiar algunos parámetros en el momento de la ejecución de la aplicación, se debe añadir un segundo parámetro en la llamada al método createEntityManagerFactory, asignando una serie de propiedades en un objeto de tipo Map, como se muestra en este código:

Map<String, String> emfProperties = new HashMap<String, String>();
// emfProperties.put("javax.persistence.jdbc.user", "root");
// emfProperties.put("javax.persistence.jdbc.password", "root");
emfProperties.put("javax.persistence.schema-generation.database.action", "create");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("AgendaContactosPU", emfProperties);
EntityManager em = emf.createEntityManager();

Como puedes ver en el código anterior, también se pueden asignar otras propiedades como el nombre de usuario y contraseña de acceso a la base de datos (aparecen como un comentario para tenerlo de muestra), por si se desean utilizar otros datos diferentes a los que figuran en el archivo persistence.xml.

Asignar URL relativa

En la configuración que se ha realizado para conectar NetBeans con la base de datos, se ha especificado una URL con la dirección absoluta (desde la carpeta raíz) a la carpeta donde se está desarrollando el proyecto, para que tanto desde las herramientas propias de NetBeans como desde nuestra aplicación se asegure el acceso a la misma dirección. Esto tiene el inconveniente de que cuando la aplicación se desee ejecutar en otro equipo que no sea en el que está creando la aplicación, la dirección donde se encuentre será diferente con casi total seguridad. Por ello es conveniente indicar ahora una dirección relativa para la base de datos, indicando únicamente su nombre "BDAgendaContactos", sin indicar la ruta (si se desea se puede indicar una carpeta antes que el nombre de la base de datos si se quiere organizar de otra manera, pero sin empezar por / para que sea una ruta relativa, por ejemplo, "Basedatos/BDAgendaContactos".

La nueva dirección se puede indicar en el archivo persistence.xml cambiando la información que aparece en JDBC Connection. Por ejemplo:

jdbc:derby:/Users/Javier/NetBeansProjects/AgendaContactos/BDAgendaContactos;create=true

Se debería poner:

jdbc:derby:BDAgendaContactos;create=true

Si se prefiere realizar este cambio a través del código fuente de la aplicación, se debe añadir una nueva propiedad al objeto Map que se pasa por parámetro al crear el EntityManagerFactory. Siguiendo con el ejemplo que se había expuesto anteriormente, se añadiría la propiedad con un código como el siguiente:

emfProperties.put("javax.persistence.jdbc.url", "jdbc:derby:BDAgendaContactos;create=true");

Cerrar la conexión

Con el fin de asegurar que los datos terminen de almacenarse correctamente y dejar las cachés en un estado correcto, una vez finalizadas todas las operaciones que vayan a realizar sobre la base de datos, se debe cerrar la conexión con ella. Utiliza los métodos close() de EntityManagerFactoryEntityManager, y para el caso del motor de base de datos Java DB (Derby) ejecutado de forma embedida en la aplicación (sin usar un servidor), se debe asegurar la terminación de la ejecución de la instancia del gestor de base de datos Derby lanzando una conexión con el parámetro shutdown=true. Esa instrucción se puede realizar expresamente sobre la base de datos abierta ("jdbc:derby:BDAgendaContactos;shutdown=true") o cerrar completamente la ejecución de Derby para cualquier base de datos abierta por la misma instancia del motor ("jdbc:derby:;shutdown=true").

em.close(); 
emf.close(); 
try { 
    DriverManager.getConnection("jdbc:derby:BDAgendaContactos;shutdown=true"); 
} catch (SQLException ex) { 
}

La llamada al método DriverManager.getConnection requiere estar encerrado obligatoriamente en una cláusula try-catch, e incluso en este caso de cerrar la ejecución de Derby, siempre se genera un error que se puede obviar, por lo que se deja vacío el bloque catch.

Código completo de la conexión y desconexión con la base de datos

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class AgendaContactos {

    public static void main(String[] args) {
        // Conectar con la base de datos
        Map<String, String> emfProperties = new HashMap<String, String>();
        emfProperties.put("javax.persistence.schema-generation.database.action", "create");
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("AgendaContactosPU", emfProperties);
        EntityManager em = emf.createEntityManager();

        // REALIZAR AQUÍ LAS OPERACIONES SOBRE LA BASE DE DATOS
        
        // Cerrar la conexión con la base de datos
        em.close(); 
        emf.close(); 
        try { 
            DriverManager.getConnection("jdbc:derby:BDAgendaContactos;shutdown=true"); 
        } catch (SQLException ex) { 
        }
    }
    
}

Más información