Entidades

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