Persistencia en JEE - JPA Ing. Cesar Julio Bustacara Medina Introducción • JPA es la nueva especificación de persistencia de Java: – Provee un estándar para realizar el mapeo objeto-relacional (OR), el cual integra muchos de los conceptos encontrados en frameworks de persistencia como Hibernate y JDO. – No es una ventaja especifica de los contenedores JEE y puede ser probado y usado en ambientes J2SE – Define una interface del prestador de servicios (Services Provider Interface – SPI) Introducción El mapeo Objeto-Relacional (OR) es un mecanismo muy sofisticado para permitir hacer persistencia de objetos Introducción • El mapeo OR puede hacerse de dos maneras: – De manera programática – Usar un producto de mapeo, tal como: Oracle TopLink, o herramientas de código abierto como Hibernate Entidades • En aplicaciones empresariales multi-tier se encuentran típicamente dos clases de objetos: • Componentes para la lógica de la aplicación – Proveen métodos que ejecutan tareas comunes. Por ejemplo: • Calcular el precio de una orden • Facturar usando una tarjeta de crédito • Calcular la inversa de una matriz Manejan normalmente el proceso del negocio : Session beans Los Session beans contienen los algoritmos y la lógica para ejecutar una tarea del negocio. Representan el trabajo que esta siendo ejecutado por un usuario, el cual incluye cualquier lógica del flujo de trabajo. Entidades • Objetos de Persistencia de Datos. – Son objetos que pueden ser guardados en un espacio de almacenamiento manejado por un mecanismo de persistencia. Esta clase de objetos representan datos simples o complejos. Por ejemplo: • Información de cuentas bancarias, tal como números de cuenta y balance • Datos de recursos humanos, tales como nombres, departamentos, y salarios de empleados Objetos de Persistencia de Datos • Las entidades de persistencia son POJOs (plain old Java objects) que son guardados en unidades de almacenamiento duradero, tal como una base de datos o sistemas legados • Las entidades almacenan datos como campos, tales como números de cuenta y balances de cuentas. • Proveen métodos asociados de tipo get y set, por ejemplo: getAccountNumber() Características • Los entities tienen un cliente visible y una identidad (Primary Key) que es diferente a su referencia • Los Entities no son accedidos de forma remota • El tiempo de vida de un Entity puede ser completamente independiente del tiempo de vida de la aplicación. Campos Persistentes y Propiedades • Los campos o propiedades deben ser de los siguientes tipos definidos en Java: – – – Java primitive types java.lang.String Otros tipos serializables incluidos: • • • • • • • • • • • • • – – – Wrappers of Java primitive types java.math.BigInteger java.math.BigDecimal java.util.Date java.util.Calendar java.sql.Date java.sql.Time java.sql.TimeStamp User-defined serializable types byte[] Byte[] char[] Character[] Tipos enumerados Otras entidades y/o colleciones de entidades Clases embebidas (inner clasess / embeddable classes) Manejo de Entidades • Los Entities son manejados por el “Entity Manager”. El entity manager es representado por instancias de javax.persistence.EntityManager. • Cada EntityManager esta sociado con un contexto de persistencia “Persistence Context”. Un persistence context define el alcance bajo el cual una entidad es creada, insertada y borrada • El Persistence Context, es un conjunto de instancias de tipo entidad manejadas que existe en un almacen de datos particular. Manejo de Entidades • La interface EntityManager define los métodos que son usados para interactuar con el persistence context. • La interface EntityManager Interface crea y borra instancias de entidades persistentes, encuentra entidades a través de la llave primaria y permite realizar consultas sobre los entities. Manejo de Entidades El EntityManager maneja la persistencia de entidades de un contexto de persistencia, existen dos formas de obtener un EntityManager: • A través del contenedor (Container-Managed EntityManagers) • A través de la aplicación (Application-Managed EntityManagers) Manejo de Entidades • Obtener la referencia al EntityManager, por inyección (Contenedor): – @PersistenceContext – private EntityManager em; • Obtener la referencia al EntityManager, por instanciación (Aplicación): – @PersistenceUnit – EntityManagerFactory emf; – EntityManager em = emf.createEntityManager(); Definición de Entidades Definición de un Entity Bean Asociación de un Entity Bean a una Tabla @Entity public class Usuarios{ ... } @Entity @Table(name = “Users_TABLE”) public class Usuarios{ ... } Asociación de una llave primaria al Entity Bean @Entity @Table(name = “Users_TABLE”) public class Usuarios { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Integer getId() { return this.id; } //AUTO, TABLE, IDENTITY or SEQUENCE } Definición de Entidades Asociación de una columna a un campo o propiedad persistente @Entity @Table(name = “Users_TABLE”) public class Usuarios{ @Basic @Column(name = “users_name") public String getName() { return this.name; } } Definición de Entidades @Entity @Table(name = “Users_TABLE”) public class Usuarios { @OneToMany(mappedBy="portfolio", cascade={CascadeType.ALL}) public Collection<Role> getRoles() { return roles; } } Manejo de entidades Servicios para obtener entidades manejadas: – persist: insert BD de una nueva entidad : em.persist(empleado); // el objeto adquiere PK – find: select BD de una entidad existente, conociendo su PK: Empleado empleado= em.find(Empleado.class, valorId); // retorna null si no lo encuentra – merge: mezcla para una entidad de su versión en memoria con su versión en la BD, prevaleciendo su versión en memoria: empleado = em.merge(empleado); Manejo de entidades Servicios sobre entidades manejadas: – refresh: select BD de una entidad existente, cancelando posibles modificaciones en memoria durante la transacción em.refresh(empleado); – remove: delete BD de una entidad existente: em.remove(empleado); – flush: aplicar a la BD modificaciones de entidades, acumuladas durante la transacción (pone candados y se somete al commit/rollback): em.flush(); //efecto visto por siguiente consulta de la transacción. //ocurre automáticamente en el commit de la transacción. Ejemplo -Entidades • Crear una tabla denominada usuarios – – – – – – Id – Numeric Nombres – Varchar2(50) Apellidos – Varchar2 (50) Login – Varchar2(20) Password – Varchar2(20) Role – Varchar2(20) CREATE TABLE USUARIOS ( id NUMBER(*, 0) NOT NULL, nombres VARCHAR2(50 BYTE), apellidos VARCHAR2(50 BYTE), login VARCHAR2(20 BYTE), password VARCHAR2(20 BYTE), role VARCHAR2(20 BYTE), CONSTRAINT USUARIOS_PK PRIMARY KEY(id)ENABLE ); Definir la Unidad de Persistencia TopLink por Omisión <?xml version="1.0" encoding="windows-1252" ?> <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_1_0.xsd" version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="unidadpersistencia01"> <jta-data-source> OracleDS </jta-data-source> <properties> <property name="toplink.target-server" value="JBoss"/> </properties> </persistence-unit> </persistence> Definir la Unidad de Persistencia Modificar a Hibernate <?xml version="1.0" encoding="windows-1252" ?> <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_1_0.xsd" version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name=“unidadpersistencia01"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source> java:OracleDS </jta-data-source> <class> ejemplo01.Usuarios </class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/> <property name="hibernate.hbm2ddl.auto" value=“update"/> </properties> </persistence-unit> </persistence> Ejemplo Usuarios.java (Entity) import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; @Entity @NamedQueries({ @NamedQuery(name = "Usuarios.findAll", query = "select o from Usuarios o"), @NamedQuery(name = "Usuarios.findAll.size", query = "select count(o) from Usuarios o") }) public class Usuarios implements Serializable { @Id @Column(nullable = false) private Long id; private String nombres; private String apellidos; private String login; private String password; private String role; public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getNombres() { return nombres; } public void setNombres(String nombres) { this.nombres = nombres; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } } Crear EJB de Session Interfaces remota/local @Remote public interface UsuariosEJB { Object mergeEntity(Object entity); Object persistEntity(Object entity); List<Usuarios> queryUsuariosFindAll(); List<Usuarios> queryUsuariosFindAllByRange(int firstResult, int maxResults); Number queryUsuariosFindAllSize(); void removeUsuarios(Usuarios usuarios); } @Local public interface UsuariosEJBLocal { } EJB de Session @Stateless(name="UsuariosEJB") public class UsuariosEJBBean implements UsuariosEJB, UsuariosEJBLocal { @PersistenceContext(unitName="unidadpersistencia01") private EntityManager em; public UsuariosEJBBean() { } public Object mergeEntity(Object entity) { return em.merge(entity); } public Object persistEntity(Object entity) { em.persist(entity); return entity; } /** <code>select o from Usuarios o</code> */ public List<Usuarios> queryUsuariosFindAll() { return em.createNamedQuery("Usuarios.findAll").getResultList(); } /** <code>select o from Usuarios o</code> */ public List<Usuarios> queryUsuariosFindAllByRange(int firstResult, int maxResults) { Query query = em.createNamedQuery("Usuarios.findAll"); if (firstResult > 0) { query = query.setFirstResult(firstResult); } if (maxResults > 0) { query = query.setMaxResults(maxResults); } return query.getResultList(); } /** <code>select count(o) from Usuarios o</code> */ public Number queryUsuariosFindAllSize() { return (Number)em.createNamedQuery("Usuarios.findAll.size").getSingleResult(); } public void removeUsuarios(Usuarios usuarios) { usuarios = em.find(Usuarios.class, usuarios.getId()); em.remove(usuarios); } } Crear el Cliente para adicionar Usuarios public class AdicionarUsuariosEJBClient { public static void main(String [] args) { try { final Context context = getInitialContext(); UsuariosEJB usuariosEJB = (UsuariosEJB)context.lookup("UsuariosEJB/remote"); // Crear un usuario Usuarios usuario = new Usuarios(); usuario.setId(new Long(1)); usuario.setNombres("Cesar"); usuario.setApellidos("Bustacara"); usuario.setLogin("admin"); usuario.setPassword("admin"); usuario.setRole("admin"); // Adicionar el usuario a la BD usuariosEJB.persistEntity(usuario); // Crear un usuario usuario = new Usuarios(); usuario.setId(new Long(2)); usuario.setNombres("Carlos"); usuario.setApellidos("Medina"); usuario.setLogin("usuario"); usuario.setPassword("usuario"); usuario.setRole("usuario"); // Adicionar el usuario a la BD usuariosEJB.persistEntity(usuario); } catch (Exception ex) { ex.printStackTrace(); } } public Object persistEntity(Object entity) { em.persist(entity); return entity; } Crear el Cliente para adicionar Usuarios… private static Context getInitialContext() throws NamingException { Hashtable environment = new Hashtable(); environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); environment.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); environment.put(Context.PROVIDER_URL, "jnp://localhost:1099"); // IP Maquina Remota InitialContext context = new InitialContext(environment); return context; } } Crear el Cliente para consultar Usuarios public class UsuariosEJBClient { public static void main(String [] args) { try { final Context context = getInitialContext(); UsuariosEJB usuariosEJB = (UsuariosEJB)context.lookup("UsuariosEJB/remote"); for (Usuarios usuarios : (List<Usuarios>)usuariosEJB.queryUsuariosFindAll()) { System.out.println( "id = " + usuarios.getId() ); System.out.println( "nombres = " + usuarios.getNombres() ); System.out.println( "apellidos = " + usuarios.getApellidos() ); System.out.println( "login = " + usuarios.getLogin() ); System.out.println( "password = " + usuarios.getPassword() ); System.out.println( "role = " + usuarios.getRole() ); } for (Usuarios usuarios : (List<Usuarios>)usuariosEJB.queryUsuariosFindAllByRange( 0, 10 )) { System.out.println( "id = " + usuarios.getId() ); System.out.println( "nombres = " + usuarios.getNombres() ); System.out.println( "apellidos = " + usuarios.getApellidos() ); System.out.println( "login = " + usuarios.getLogin() ); System.out.println( "password = " + usuarios.getPassword() ); System.out.println( "role = " + usuarios.getRole() ); } } catch (Exception ex) { ex.printStackTrace(); } } /** <code>select o from Usuarios o</code> */ public List<Usuarios> queryUsuariosFindAll() { return em.createNamedQuery("Usuarios.findAll").getResultList(); } Ejercicio práctico • Unir todos los conceptos vistos para desarrollar una aplicación N-Tier que permita: – Administrar usuarios – Validar ingreso de usuarios
© Copyright 2024