daw 2 sesion 04 jpa-web archivos y transacciones

26
GUIA DE LABORATORIO 1 JAVA PERSISTENCE API OBJETIVOS: 1. Conocer las características y ventajas que brinda JPA (Java Persistence API) como framework ORM (Object Relational Mapping) para la integración de aplicaciones Java con Bases de Datos Relacionales. 2. Conocer las consideraciones a tener en cuenta para utilizar la API de JPA, basada en la implementación de EclipseLink, tanto en aplicaciones Stand-alone como en Apache Tomcat. TEMAS: 1. Introducción 2. JPA CRUD Tabla independiente: 2.1. Aplicación Stand-Alone 2.2. Aplicación Web usando Tomcat: Struts 2/Servicios/JPA 3. JPA CRUD – Tablas relacionadas 3.1. Aplicación Stand-Alone 3.2. Aplicación Web usando Tomcat: Struts 2/Servicios/JPA 4. JPA Transacciones: Aplicación Web usando Tomcat con JTA 5. Referencias

Upload: john-rodrigo-oscco-poma

Post on 27-Nov-2014

617 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

GUIA DE LABORATORIO1

JAVA PERSISTENCE API

OBJETIVOS:

1. Conocer las características y ventajas que brinda JPA (Java Persistence API) como framework ORM (Object Relational Mapping) para la integración de aplicaciones Java con Bases de Datos Relacionales.

2. Conocer las consideraciones a tener en cuenta para utilizar la API de JPA, basada en la implementación de EclipseLink, tanto en aplicaciones Stand-alone como en Apache Tomcat.

TEMAS:

1. Introducción

2. JPA CRUD – Tabla independiente:

2.1.Aplicación Stand-Alone2.2.Aplicación Web usando Tomcat: Struts 2/Servicios/JPA

3. JPA CRUD – Tablas relacionadas

3.1.Aplicación Stand-Alone3.2. Aplicación Web usando Tomcat: Struts 2/Servicios/JPA

4. JPA Transacciones: Aplicación Web usando Tomcat con JTA

5. Referencias

La guía se complementa con la explicación en clase por parte del Docente y los trabajos propios del alumno.

Page 2: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

JPA – Miscelanea

Aplicación Web usando Tomcat: Struts 2/Servicios/JPA

CASO : Registro y visualización de una Imagen

En este ejemplo vamos a implementar la funcionalidad de registro de archivos con Struts2(upload) y JPA(persist Lob).

Se ha añadido a la entidad Empleado, un campo para almacenar la foto personal del cada empleado.

Diagrama de Clases

Modelo de Datos

Page 3: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

SCRIPT

CREATE DATABASE IF NOT EXISTS mysqljpa;USE mysqljpa;

DROP TABLE IF EXISTS tb_empleado;DROP TABLE IF EXISTS tb_cargo;DROP TABLE IF EXISTS tb_casillero;

CREATE TABLE tb_cargo ( id_cargo int(10) unsigned NOT NULL AUTO_INCREMENT, descripcion varchar(45) DEFAULT NULL, PRIMARY KEY (id_cargo));

CREATE TABLE tb_casillero ( id_casillero int(10) unsigned NOT NULL AUTO_INCREMENT, descripcion varchar(4) NOT NULL, PRIMARY KEY (id_casillero));

CREATE TABLE tb_empleado ( id_empleado int(10) unsigned NOT NULL AUTO_INCREMENT, nombre varchar(45) NOT NULL, apellido varchar(45) NOT NULL, edad int(10) unsigned NOT NULL, foto longblob, id_cargo int(10) unsigned NOT NULL, id_casillero int(10) unsigned NOT NULL, PRIMARY KEY (id_empleado), KEY FK_empleado_cargo (id_cargo), KEY FK_tb_empleado_casillero (id_casillero), CONSTRAINT FK_empleado_cargo FOREIGN KEY (id_cargo) REFERENCES tb_cargo (id_cargo), CONSTRAINT FK_tb_empleado_casillero FOREIGN KEY (id_casillero) REFERENCES tb_casillero (id_casillero));

INSERT INTO tb_cargo (id_cargo,descripcion) VALUES (1,'secretaria');

Page 4: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Paso 1: Importar Proyecto “DAW2-Semana-06-JPA-CasoImagen-BaseAPP”

a. Hay que añadir las librerías *. jar de Eclipse Link 2.1.x1 a la carpeta lib.

Revisión de cambios en capa presentación para realizar el Upload de archivo:

EmpleadoDTO

public class EmpleadoDTO implements Serializable {

private Integer codigo;private String nombre;private String apellido;private Integer edad;private byte[] foto;private CargoDTO cargo;private CasilleroDTO casillero;

//objetos de ayuda para manejo de archivosprivate File archivo;private String archivoFileName;private String archivoContentType;private InputStream isFoto;

public EmpleadoDTO() {}

public EmpleadoDTO(Integer codigo, String nombre,String apellido, Integer edad, byte[] foto,CargoDTO cargo, CasilleroDTO casillero) {

super();this.codigo = codigo;this.nombre = nombre;this.apellido = apellido;this.edad = edad;this.foto= foto;this.cargo= cargo;this.casillero = casillero;

}

1 http://www.eclipse.org/eclipselink/downloads/index.php

Page 5: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

CASO 1.1: REGISTRO DE IMAGEN

EmpleadoForm.jsp

<s:form method="post" enctype="multipart/form-data"> <s:hidden name="empleado.codigo"/> <table align="center" class="borderAll"> <tr><td class="tdLabel"><s:text name="label.nombre"/></td> <td><s:textfield name="empleado.nombre" size="30"/></td> </tr> <tr> <td class="tdLabel"><s:text name="label.apellido"/></td> <td><s:textfield name="empleado.apellido" size="30"/></td> </tr> <tr><td class="tdLabel"><s:text name="label.edad"/></td> <td><s:textfield name="empleado.edad" size="20"/></td> </tr> <tr><td class="tdLabel"><s:text name="label.cargo"/></td> <td><s:select name="empleado.cargo.codigo"

list="cargos" listKey="codigo" listValue="descripcion"key="empleado.cargo.codigo"></s:select>

</td> </tr> <tr><td class="tdLabel"><s:text name="label.casillero"/></td> <td><s:textfield name="empleado.casillero.descripcion" size="4"/></td> </tr> <tr><td class="tdLabel"><s:text name="label.foto"/></td> <td><s:file name="empleado.archivo"/></td> </tr> </table> <br/> <table> <tr> <td><s:submit action="insertarOActualizar" key="button.label.submit" cssClass="butStnd"/></td> <td><s:reset key="button.label.cancel" cssClass="butStnd"/></td> </tr> </table> </s:form>

EmpleadoAction.java

// Metodo 3: inserta o actualiza un empleado public String insertarOActualizar() throws Exception{

//cargando arrar de bytes desde el archivo.if(empleado.getArchivo()!=null){

InputStream is=new FileInputStream(empleado.getArchivo());byte[] b3 = new byte[is.available()];is.read(b3);

empleado.setFoto(b3);

}

if (empleado.getCodigo() == null) {empService.insertarEmpleado(empleado);

} else {empService.actualizarEmpleado(empleado);

} return "success"; }

Page 6: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

CASO 1.2: VISUALIZAR IMAGEN

EmpleadoDetail.jsp

<table align="center" class="borderAll"> <tr><td class="tdLabel"><s:text name="label.nombre"/></td> <td><s:property value="empleado.nombre"/></td> </tr> <tr> <td class="tdLabel"><s:text name="label.apellido"/></td> <td><s:property value="empleado.apellido"/></td> </tr> <tr><td class="tdLabel"><s:text name="label.edad"/></td> <td><s:property value="empleado.edad"/></td> </tr> <tr><td class="tdLabel"><s:text name="label.cargo"/></td> <td><s:property value="empleado.cargo.descripcion"/></td> </tr> <tr><td class="tdLabel"><s:text name="label.casillero"/></td> <td><s:property value="empleado.casillero.descripcion"/>

</td> </tr> <tr><td class="tdLabel"><s:text name="label.foto"/></td> <td><img alt="Foto " src="detalleFoto?codigo=${empleado.codigo }" />

</td> </tr>

</table>

EmpleadoAction.java

// Metodo 6: Obtener foto de Empleado public String detalleFotoEmpleado() throws Exception{

ActionContext context = ActionContext.getContext(); String[] a=(String[])context.getParameters().get("codigo");

empleado=new EmpleadoDTO(); empleado.setCodigo(Integer.parseInt(a[0])); empleado = empService.obtenerEmpleado(empleado);

InputStream is = new ByteArrayInputStream(empleado.getFoto()); empleado.setIsFoto(is);

return "success";

}

Struts.xml<action name="detalleFoto" method="detalleFotoEmpleado"

class="edu.cibertec.daw2.action.EmpleadoAction"><result name="success" type="stream">

<param name="inputName">empleado.isFoto</param></result>

</action>

Nota: En el caso detalle, optimizar la funcionalidad para evitar realizar doble busqueda de la misma Entidad.(Ejm: Manejo de objeto EmpleadoDTO en Sesión)

En este caso nos vamos a centrar en la aplicación de JPA que permita registrar la foto de un Empleado.

Page 7: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Paso 2: Dentro del paquete edu.cibertec.persistence.entity :

(a) Actualizar clase “Empleado.java” con la siguiente propiedad:

Crear los métodos getter/setter.

@Entity@Table(name="tb_empleado")public class Empleado implements Serializable{

@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="id_empleado")private int codigo;

private String nombre;private String apellido;private int edad;

private byte[] foto;

.....

Page 8: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Paso 3: Aplicando ORM con @Anotaciones

a) Para el manejo de archivos, se utilizará la anotación @Lob

@Entity@Table(name="tb_empleado")public class Empleado implements Serializable{

@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="id_empleado")private int codigo;

private String nombre;private String apellido;private int edad;

@Lobprivate byte[] foto;

.....

Paso 4: Actualización de métodos en EmpleadoJPADAO

@Overridepublic List<EmpleadoDTO> obtenerTodos() throws Exception {

em=emf.createEntityManager();

List<EmpleadoDTO> empleados = new ArrayList<EmpleadoDTO>(); // 1. Buscar empleados con JPQLList l = em.createQuery( "SELECT c FROM Empleado c ORDER BY c.codigo" ).getResultList();

// 2. Copiar los datos de cada entidad a DTOfor ( int i=0; i < l.size(); i++ ) {

Empleado entidadEmpleado = (Empleado)l.get(i);

Cargo entidadCargo=entidadEmpleado.getCargo();CargoDTO cargoDTO=new CargoDTO(new Integer(entidadCargo.getCodigo()) , entidadCargo.getDescripcion());

Casillero entidadCasillero=entidadEmpleado.getCasillero();CasilleroDTO casilleroDTO=new CasilleroDTO(new Integer(entidadCasillero.getCodigo()) , entidadCasillero.getDescripcion());

EmpleadoDTO dto = new EmpleadoDTO(new Integer(entidadEmpleado.getCodigo()) , entidadEmpleado.getNombre(), entidadEmpleado.getApellido(), entidadEmpleado.getEdad(),entidadEmpleado.getFoto(), cargoDTO,casilleroDTO);

empleados.add( dto );}

em.close();

return empleados;}

Page 9: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

@Overridepublic void insertar(EmpleadoDTO empleadoDTO) throws Exception {

em=emf.createEntityManager();

//1.inicia la transacciónem.getTransaction().begin();

Cargo entidadCargo=new Cargo();entidadCargo.setCodigo(empleadoDTO.getCargo().getCodigo());

Casillero entidadCasillero=new Casillero();entidadCasillero.setDescripcion(empleadoDTO.getCasillero().getDescripcion());

Empleado entidadEmpleado=new Empleado();

entidadEmpleado.setNombre( empleadoDTO.getNombre() );entidadEmpleado.setApellido(empleadoDTO.getApellido() );entidadEmpleado.setEdad( empleadoDTO.getEdad() );entidadEmpleado.setFoto(empleadoDTO.getFoto());entidadEmpleado.setCargo( entidadCargo);entidadEmpleado.setCasillero( entidadCasillero);

//2.ejecuta las operacionesem.persist(entidadEmpleado);em.flush();

//3.ejecuta commit a la transacciónem.getTransaction().commit();em.close();

}

@Overridepublic void actualizar(EmpleadoDTO empleadoDTO) throws Exception {

em=emf.createEntityManager();

//1.inicia la transacciónem.getTransaction().begin();

Cargo entidadCargo=new Cargo();entidadCargo.setCodigo(empleadoDTO.getCargo().getCodigo());

Casillero entidadCasillero=new Casillero();entidadCasillero.setDescripcion(empleadoDTO.getCasillero().getDescripcion());

//2. ejecuta las operaciones //2.1 busca Empleado por llave primariaEmpleado entidadEmpleado = em.find(Empleado.class, empleadoDTO.getCodigo() );

//2.2 actualizamos los datosentidadEmpleado.setNombre( empleadoDTO.getNombre() );entidadEmpleado.setApellido(empleadoDTO.getApellido() );entidadEmpleado.setEdad( empleadoDTO.getEdad() );entidadEmpleado.setCargo( entidadCargo );entidadEmpleado.setCasillero( entidadCasillero);if(empleadoDTO.getFoto()!=null)

entidadEmpleado.setFoto(empleadoDTO.getFoto());

//2.3 actualiza Empleadoem.merge(entidadEmpleado);em.flush();

//3.ejecuta commit a la transacciónem.getTransaction().commit();em.close();

}

Page 10: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

@Overridepublic void eliminar(EmpleadoDTO empleadoDTO) throws Exception {

em=emf.createEntityManager();

//1.inicia la transacciónem.getTransaction().begin();

//2. ejecuta las operaciones

//2.1 busca Empleado por llave primariaEmpleado entidadEmpleado=(Empleado)em.find(Empleado.class,empleadoDTO.getCodigo());//2.2 elimina Empleadoem.remove(entidadEmpleado);em.flush();

//3.ejecuta commit a la transacciónem.getTransaction().commit();em.close();

}

@Overridepublic EmpleadoDTO obtenerEmpleado(EmpleadoDTO empleadoDTO) throws Exception {

em=emf.createEntityManager();

Empleado entidadEmpleado=(Empleado)em.find(Empleado.class,empleadoDTO.getCodigo());

Cargo entidadCargo=entidadEmpleado.getCargo();

CargoDTO cargoDTO=new CargoDTO(new Integer(entidadCargo.getCodigo()) , entidadCargo.getDescripcion());

Casillero entidadCasillero=entidadEmpleado.getCasillero();CasilleroDTO casilleroDTO=new CasilleroDTO(new Integer(entidadCasillero.getCodigo()), entidadCasillero.getDescripcion());

EmpleadoDTO dto = new EmpleadoDTO(new Integer(entidadEmpleado.getCodigo()) , entidadEmpleado.getNombre(), entidadEmpleado.getApellido(), entidadEmpleado.getEdad(),entidadEmpleado.getFoto(), cargoDTO,casilleroDTO);

em.close();

return dto;}

PASO 5: Probar ejecutando la aplicación con “Run” – “Run As Server”

El mantenimiento inicia con la opción “CRUD Empleados” del Menú.

¿Cuál es el comportamiento del aplicativo? Revisar la secuencia de ejecución.

¡ Felicitaciones ! Estamos listos para seguir aprendiendo ….

Page 11: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

4. JPA – Transacciones

Todas las entidades son transaccionales.

En JPA se puede configurar dos tipos de transacciones: Resource-local y JTA

Resource-local: Este tipo de transacción permite al programador controlar y validar la ejecucion de las transacciones, por lo cual determinará cuando enviar la transacción a la base de datos (commit) ó cuando cancelar una transacción(rollback).

JTA: Con este tipo de transacción, el programador no debe preocuparse por la parte transaccional, ya que es el Contenedor de aplicaciones el que se encargará de realizar los commit ó rollback de manera automática.

Vamos a configurar ambos tipos de transacciones, utilizando el proyecto WEB del ejemplo anterior:

Configuración en el archivo persistence.xml.

TRANSACCION Resource-local: <?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="JPA-Web" transaction-type="RESOURCE_LOCAL">

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

<class>edu.cibertec.daw2.entity.Cargo</class><class>edu.cibertec.daw2.entity.Empleado</class><class>edu.cibertec.daw2.entity.Casillero</class>

<properties> <property name="eclipselink.jdbc.driver"

value="com.mysql.jdbc.Driver"/> <property name="eclipselink.jdbc.url"

value="jdbc:mysql://localhost:3306/mysqljpa"/> <property name="eclipselink.jdbc.user" value="root"/> <property name="eclipselink.jdbc.password" value="mysql"/> <property name="eclipselink.logging.level" value="FINE"/> </properties>

</persistence-unit></persistence>

Page 12: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Vamos a añadir una simulación de error al metodo insertar() de EmpleadoJPADAO, para dar un rollback a la transacción:

public void insertar(EmpleadoDTO empleadoDTO) throws Exception {

em=emf.createEntityManager();

//1.inicia la transacciónem.getTransaction().begin();

Cargo entidadCargo=new Cargo();entidadCargo.setCodigo(empleadoDTO.getCargo().getCodigo());

Casillero entidadCasillero=new Casillero();entidadCasillero.setDescripcion(empleadoDTO.getCasillero().getDescripcion());

Empleado entidadEmpleado=new Empleado();

entidadEmpleado.setNombre( empleadoDTO.getNombre() );entidadEmpleado.setApellido(empleadoDTO.getApellido() );entidadEmpleado.setEdad( empleadoDTO.getEdad() );entidadEmpleado.setFoto(empleadoDTO.getFoto());entidadEmpleado.setCargo( entidadCargo);entidadEmpleado.setCasillero( entidadCasillero);

//2.ejecuta las operacionesem.persist(entidadEmpleado);em.flush();

//simulacion de error: ejecutar rollbackif(empleadoDTO.getEdad()==45){

em.getTransaction().rollback();em.close();return;

}

//3.ejecuta commit a la transacciónem.getTransaction().commit();em.close();

}

Nota:Realiza pruebas ingresando edad=45 y edad=40;Observe la ejecución de Insert en el log y revise el registro en la tabla tb_empleado.¿Cuál es la diferencia?

Page 13: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

TRANSACCION JTA:

Para poder utilizar JTA, se requiere definir un DATASOURCE con JNDI.

Paso 1: En Tomcat, definimos un Datasource de la siguiente forma: en Eclipse dar click al

folder de “Servers”:

Editamos el archivo context.xml ( con el servidor detenido ) y agregamos el siguiente bloque:

<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="10" name="jdbc/daw2" username="root" password="mysql" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/mysqljpa">

</Resource>

Observe que se está indicando CUAL es el driver de conexión JDBC, por tanto, la librería correspondiente debe estar en el CLASSPATH del servidor Tomcat.

El atributo “name” especifica el nombre JNDI con el cual, las aplicaciones referenciarán a la conexión establecido por el Tomcat contra la Base de Datos

<?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="JPA-Web" transaction-type = "JTA" > <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

<class>edu.cibertec.daw2.entity.Cargo</class><class>edu.cibertec.daw2.entity.Empleado</class><class>edu.cibertec.daw2.entity.Casillero</class>

<properties> <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="eclipselink.jdbc.url"

value="jdbc:mysql://localhost:3306/mysqljpa"/> <property name="eclipselink.jdbc.user" value="root"/> <property name="eclipselink.jdbc.password" value="mysql"/> <property name="eclipselink.logging.level" value="FINE"/> </properties>

</persistence-unit></persistence>

Page 14: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Paso 2:

Para usar JTA con DataSources, editamos en el archivo persistence.xml los siguientes cambios:

Primero debemos indicar que la unidad de persistencia será JTA: modificar el valor del atributo “transaction-type”:

<persistence-unit name="JPA-Web" transaction-type = "JTA" >

Luego debemos indicar que se usará el dataSource ( que debe ser escrito con el mismo nombre con el que se definió en Tomcat ).

<jta-data-source>java:comp/env/jdbc/daw2</jta-data-source>

Tenga en cuenta que en el archivo context.xml se colocó un atributo “name” únicamente con el valor “jdbc/daw2”. Observe la forma en que se referencia aquí.

Tomcat requiere que al usar JTA se especifique una clase “Session Customizer” 2

que se encargue de modificar al conector para ubicar correctamente al datasource. Hay que definirla y crearla.

<property name="eclipselink.session.customizer" value="org.eclipse.persistence.example.unified.integration.JPAEclipseLinkSessionCustomizer"/>

Asi quedará el archivo persistence.xml

<?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="JPA-Web" transaction-type="JTA">

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

<jta-data-source>java:comp/env/jdbc/daw2</jta-data-source>

<class>edu.cibertec.daw2.entity.Cargo</class><class>edu.cibertec.daw2.entity.Empleado</class><class>edu.cibertec.daw2.entity.Casillero</class>

<properties><property name="eclipselink.session.customizer"

value="org.eclipse.persistence.example.unified.integration.JPAEclipseLinkSessionCustomizer"/>

<property name="eclipselink.logging.level" value="FINE"/>

</properties></persistence-unit>

</persistence>

2 Ver: http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial

Page 15: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Paso 3:

Crearemos un paquete org.eclipse.persistence.example.unified.integration

Dentro del paquete, crear una clase llamada “JPAEclipseLinkSessionCustomizer.java” y escribir el siguiente código tomado de la página web de Eclipse (http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial )

package org.eclipse.persistence.example.unified.integration;

import javax.naming.Context;import javax.naming.InitialContext; import org.eclipse.persistence.config.SessionCustomizer;import org.eclipse.persistence.sessions.DatabaseLogin;import org.eclipse.persistence.sessions.JNDIConnector;import org.eclipse.persistence.sessions.Session;import org.eclipse.persistence.sessions.server.ServerSession; /** * See http://wiki.eclipse.org/Customizing_the_EclipseLink_Application_(ELUG) * Use for clients that would like to use a JTA SE pu instead of a RESOURCE_LOCAL SE pu. */public class JPAEclipseLinkSessionCustomizer implements SessionCustomizer { /** * Get a dataSource connection and set it on the session with lookupType=STRING_LOOKUP */ public void customize(Session session) throws Exception { JNDIConnector connector = null; Context context = null; try { context = new InitialContext(); if(null != context) { connector = (JNDIConnector)session.getLogin().getConnector(); // possible CCE // Change from COMPOSITE_NAME_LOOKUP to STRING_LOOKUP // Note: if both jta and non-jta elements exist this will only change the first one // and may still result in the COMPOSITE_NAME_LOOKUP being set // Make sure only jta-data-source is in persistence.xml with no non-jta-data-source property set connector.setLookupType(JNDIConnector.STRING_LOOKUP); // Or, if you are specifying both JTA and non-JTA in your persistence.xml //then set both connectors to be safe JNDIConnector writeConnector = (JNDIConnector)session.getLogin().getConnector(); writeConnector.setLookupType(JNDIConnector.STRING_LOOKUP); JNDIConnector readConnector = (JNDIConnector)((DatabaseLogin)((ServerSession)session).getReadConnectionPool().getLogin()).getConnector(); readConnector.setLookupType(JNDIConnector.STRING_LOOKUP); System.out.println("_JPAEclipseLinkSessionCustomizer: configured " + connector.getName()); } else { throw new Exception( "_JPAEclipseLinkSessionCustomizer: Context is null" ); } } catch(Exception e) { e.printStackTrace(); } }}

Page 16: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Paso 4: Ya no son necesarios las invocaciones al método commit() en las clases DAO.

Paso 5: Probar nuevamente.

¡ Felicitaciones ! Estamos listos para seguir aprendiendo ….

Page 17: DAW 2 Sesion 04 JPA-Web Archivos y Transacciones

Referencias

Documentación y tutoriales:

Java EE http://www.oracle.com/technetwork/java/javaee/overview/index.html

Struts 2 http://struts.apache.org

JPA http://download.oracle.com/javaee/5/tutorial/doc/bnbpy.htmlhttp://download.oracle.com/docs/cd/B31017_01/web.1013/b28221/prt_ent30.htm#sthref776

Implementación de JPA: EclipseLink 2.1.1 http://www.eclipse.org/eclipselink/jpa.php

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial

Herramientas:

Eclipse http://www.eclipse.org

Java JSE 6: http://www.oracle.com

Apache Tomcat http://tomcat.apache.org

MySql Community Server http://www.mysql.com