DEPARTAMENTO DE SISTEMAS
Arquitecturas de Software
Entity Beans
Agenda
DEPARTAMENTO DE SISTEMAS
Generalidades de las entidades JEE
Propósito
Conceptos
Características
Mapeo con la BD
Administración de Entidades
Apoyo al desarrollo de aplicaciones
Helpers
Listener
Finders
Configuración
Generalidades
DEPARTAMENTO DE SISTEMAS
Simplificar el modelo de persistencia: modelos livianos en
términos de
Programación
Deployment
Ejecución
Modelo del
polimorfismo
Mapeo O/R
Uso extensivo de las capacidades de consulta
Mezcla de experiencias reunidas en un API (Java Persistence
API)
dominio
en
términos
Hibernate, JDO, TopLink, EJB
objetos:
herencia,
Generalidades
DEPARTAMENTO DE SISTEMAS
• Enterprise Java Beans 3.0 Persistence
o
o
o
o
Especificación creada por SUN
Persistencia de POJOs a cualquier RDBMS
Requiere Java 5
Uso de anotaciones y generics
Tomado de: http://edocs.bea.com/kodo/docs41/full/html/ejb3_overview_arch.html
Generalidades
DEPARTAMENTO DE SISTEMAS
•
EntityManagerFactory
o
•
Persistence
o
•
o
Objetos persistentes
EntityTransaction
o
•
Interface usada para persistencia de EJBs
Fábrica para instancia de queries
Entity
o
•
Contiene métodos de clase (estáticos) para obtener instancias de
EntityManagerFactory
EntityManager
o
•
Factory para EntityManagers
Manejo de transacciones entre entities
Query
o
Interface implementada por cada fabricante para encontrar objetos
persistente
EJB Query Language (JPQL)
Structured Query Language (SQL)
Conceptos
DEPARTAMENTO DE SISTEMAS
Entidad es un POJO
Plain Old Java Object + anotaciones
@Entity
public class miEntidadBean {
...
}
Conceptos (cont.)
DEPARTAMENTO DE SISTEMAS
Objetos de negocio representados por un componente que
facilita su administración y búsqueda
Representan una visión orientada-objetos de una colección
de entidades persistentes
Se encuentran en algún repositorio de datos o son
proveídos por un sistema de información externo
El bean de entidad sobrevive a la sesión y a fallas en el
sistema
Cada instancia de un bean de entidad tiene una
identificación única que corresponde a la llave primaria en el
repositorio
Ejemplo
DEPARTAMENTO DE SISTEMAS
@Entity
public class Customer implements Serializable {
private Long id;
private String name;
private Address address;
// No argument constructor
public Customer() {}
@Id
public Long getID() {
return id;
}
private void setID (Long id) {
this.id = id;
}…
Clase de Entidad
DEPARTAMENTO DE SISTEMAS
Debe tener la anotación javax.persistence.Entity y en ciertos casos
implementar Serializable
@Entity(access=AccessType.FIELD)
public class miEntidadBean implements Serializable
Lugar donde se utiliza la anotación para indicar el manejo de persistencia de
atributos
Field access—Se especifica en los atributos. Todos los atributos no transcientes
persisten
Property access— Se especifica en los métodos getter. Todas las propiedades
públicas, protegidas y no transcientes persisten. Este es el valor por defecto
Pueden extender clases de entidad o no entidad, una clase que no es de
entidad puede extender una clase de entidad
Debe tener un constructor público sin parámetros
No debe tener campos, atributos ni métodos finales
Todo atributo persistente debe ser privado y ofrecer métodos get/set
Los atributos de tipo colección deben usar las interfaces del framework
java.util.Collection con genéricos de Java 5 (Collection, Set, Map, etc.)
Identificación de Instancias
DEPARTAMENTO DE SISTEMAS
Cada instancia de una entidad tiene una llave primaria que lo identifica
Las llaves primarias simples usan la anotación javax.persistence.Id en el
método get (o en el atributo) para señalar que un atributo es la llave primaria
@Id
@GeneratedValue
public Long getId() { return id;}
Tipos válidos: primitivos, wrappers, String, Date
Es posible definir clases compuestas para llaves primarias (deben ser
serializables)
@IdClass(com.example.PersonPK.class)
@Entity(access=AccessType.FIELD)
class Person {
@Id String firstName;
@Id String lastName;
Relaciones entre entidades
DEPARTAMENTO DE SISTEMAS
Una de las principales innovaciones de JEE es la definición de
relaciones entre entidades
Existen 4 tipos de relaciones
Uno a Uno
Uno a Muchos
Muchos a Uno
Muchos a Muchos
La dirección de una relación puede ser bidireccional o
unidireccional
Una relación tiene un lado dueño (owner): determina como se
podrán propagar las modificaciones
Las relaciones bidireccionales tienen además un lado inverso
Relaciones entre entidades
DEPARTAMENTO DE SISTEMAS
Una relación es marcada en un atributo usando las anotaciones
javax.persistence.OneToOne
javax.persistence.OneToMany
javax.persistence.ManyToOne
javax.persistence.ManyToMany
Carga en memoria de las relaciones: indica el momento en el cual los
datos asociados al campo relacionado con otra entidad son cargados en
memoria
EAGER: cuando se carga la clase dueña que tiene la relación
LAZY: cuando se utiliza el campo que representa la relación
Ejemplos
@ManyToMany (fetch = FetchType.EAGER)
public Collection<Producto> getProductos()
@OneToOne
public Usuario getUsuario()
Relaciones Bidireccionales
DEPARTAMENTO DE SISTEMAS
Se puede navegar en ambas direcciones
Deben cumplir las siguientes reglas
El lado inverso de la relación debe referenciar el lado dueño usando el
elemento mappedBy en la anotación de la relación
En la relación muchos a uno o muchos a muchos el lado dueño es el
lado de muchos
En las relaciones uno a uno el dueño corresponde al lado que tiene la
llave foránea
Ejemplos
Customer.java
@OneToMany (mappedBy = “customer”)
public Collection<Order> getOrders()
Order.java
private Customer customer;
@ManyToOne
public Customer getCustomer()
Relaciones
DEPARTAMENTO DE SISTEMAS
Las entidades relacionadas pueden tener dependencias de
existencia
Las operaciones a propagar corresponden a eliminación,
actualización, inserción
Las relaciones candidatas a especificar la propagación son
@OneToOne y @OneToMany
Las entidades inversas especifican en la relación el valor de
propagación
utilizando
el
elemento
cascade=javax.persistence.CascadeType.ALL
Customer.java
@OneToMany(cascade=javax.persistence.CascadeType.ALL,
mappedBy=“customer")
public Collection<LineItem> getItems(){ return items;}
Relaciones
DEPARTAMENTO DE SISTEMAS
• @OneToOne
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
String mappedBy() default "";
}
Relaciones
DEPARTAMENTO DE SISTEMAS
@Entity
public class User {
@Id
protected String userId;
protected String email;
@OneToOne
protected BillingInfo billingInfo;
}
@Entity
public class BillingInfo {
@Id
protected Long billingId;
protected String creditCardType;
protected String creditCardNumber;
protected String nameOnCreditCard;
@OneToOne(mappedBy=”billingInfo”,
optional=”false”);
protected User user;
}
Ejemplo tomado de: EJB 3.0 in Action
Relaciones
DEPARTAMENTO DE SISTEMAS
• @OneToMany / @ManyToOne
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
}
Relaciones
DEPARTAMENTO DE SISTEMAS
@Entity
public class Item {
@Id
protected Long itemId;
protected String title;
@OneToMany(mappedBy="item")
protected Set<Bid> bids;
}
@Entity
public class Bid {
@Id
protected Long bidId;
protected Double amount;
@ManyToOne
protected Item item;
}
Ejemplo tomado de: EJB 3.0 in Action
Relaciones
DEPARTAMENTO DE SISTEMAS
• @ManyToMany
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}
Relaciones
DEPARTAMENTO DE SISTEMAS
@Entity
public class Category {
@Id
protected Long categoryId;
protected String name;
@ManyToMany
protected Set<Item> items;
}
@Entity
public class Item {
@Id
protected Long itemId;
protected String title;
@ManyToMany(mappedBy=”items”)
protected Set<Category> categories;
}
Ejemplo tomado de: EJB 3.0 in Action
Agenda
DEPARTAMENTO DE SISTEMAS
Generalidades de las entidades JEE
Mapeo con la BD
Administración de Entidades
Apoyo al desarrollo de aplicaciones
Helpers
Listener
Finders
Configuración
Ejemplo de mapeo
DEPARTAMENTO DE SISTEMAS
@Entity
@table(name=customer)
public class Customer implements Serializable {
private Long id;
@Column(name=“FirstName”, nullable=false)
private String name;
@Id
@GeneratedValue
public Long getId() {…}
}…
Customer
Id
PK,SA
FirstName
Entidades
DEPARTAMENTO DE SISTEMAS
Una entidad puede corresponder a una o más tablas
...
@Entity
@Table(name="EJB_ORDER_PART")
@SecondaryTable(name="EJB_ORDER_PART_DETAIL",
pkJoinColumns={
@PrimaryKeyJoinColumn(
name="PARTNUMBER", referencedColumnName="PARTNUM"),
@PrimaryKeyJoinColumn(
name="REVISION", referencedColumnName="REVISION") })
public class Part { ... }
EJB_ORDER_PART
PartNum
Revision
PK
PK
1
2
20000101
20000102
EJB_ORDER_PART_DETAIL
PartNum
Revision
PK,FK1
PK,FK1
1
2
20000101
20000102
Mapeo de relaciones a la BD
DEPARTAMENTO DE SISTEMAS
El mapeo de las relaciones a campos en la base de datos depende del tipo de
relación
Ejemplo de relaciones bidireccionales 1 a 1:
EntityBean
Empleado
Codigo
Nombre
Empleado
Codigo
PK
EntityBean
Departamento
<<Owner>>
Numero
Jefe 0..1
Nombre
Departamento
Numero
Jefe_Codigo
PK
FK,ND
Mapeo de la herencia
DEPARTAMENTO DE SISTEMAS
Soporta varias estrategias : Una tabla, tabla por clase concreta,
tabla por clase
Una tabla
SuperClase
@Entity
@Table(name = "record")
@Inheritance(discriminatorValue="B")
@DiscriminatorColumn(name="record_type")
public class Record implements Serializable {
protected int id;
protected double saving;
protected double result;
SubClase
@Entity
@Inheritance(discriminatorValue = "T")
public class TimeRecord extends Record {
private Timestamp ts;
Record
recordType Varchar(10)
Id Int
saving Double
result Double
Ts Datetime
Mapeo de la herencia
DEPARTAMENTO DE SISTEMAS
Una tabla por clase concreta: la tabla principal no existe necesariamente (e.g.,
clase abstracta) y se duplican los atributos comunes en las distintas tablas subtipo
SuperClase
@Entity(access=AccessType.FIELD)
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Animal {@Id protected Integer id;
… protected String name;
… protected Integer age; }
SubClase
@Entity(access=AccessType.FIELD)
public class Bird extends Animal {
… protected Integer nbPlume;
}
@Entity(access=AccessType.FIELD)
public class Dog extends Animal {
… protected String race;
}
Mapeo de la herencia
DEPARTAMENTO DE SISTEMAS
Subclases con Joins
SuperClase
@Entity(access=AccessType.FIELD)
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Employee {
@Id protected Integer id;
@Version protected Integer version;
protected String name;
SubClase1
@Entity(access=AccessType.FIELD)
@Inheritance(discriminatorValue="PT")
@PrimaryKeyJoinColumn(name="PT_EMPID")
public class PartTimeEmployee extends Employee {
protected Float hourlyWage;
SubClase2
@Entity(access=AccessType.FIELD)
@Inheritance(discriminatorValue="FT")
@PrimaryKeyJoinColumn(name="FT_EMPID")
public class FullTimeEmployee extends Employee {
protected Integer salary;
Agenda
DEPARTAMENTO DE SISTEMAS
Generalidades de las entidades JEE
Mapeo con la BD
Administración de Entidades
Apoyo al desarrollo de aplicaciones
Helpers
Listener
Finders
Configuración
Administración de Entidades
DEPARTAMENTO DE SISTEMAS
Las entidades son administradas por el Entity Manager
El Entity Manager es representado por instancias de la interfaz
javax.persistence.EntityManager
Cada instancia está asociada a un contexto persistente
Contexto Persistente: conjunto de entidades administradas que
existen en un repositorio de datos específico
La interfaz del EntityManager define métodos para interactuar con
el contexto persistente
Los componentes
persistencia
de
@PersistenceContext
EntityManager em;
aplicación
definen
el
contexto
de
Entity Manager
DEPARTAMENTO DE SISTEMAS
Similar en funcionalidad a
un Session en Hibernate Session
Un PersistenceManager en JDO
Su API ofrece servicios para
crear y remover instancias de una entidad
buscarlas por su llave primaria
ejecutar consultas sobre las entidades.
Maneja el ciclo de vida de las entidades
persist(): inserta una entidad en una BD
remove(): borrar una entidad de la BD
merge() : guardar las modificaciones hechas en la entidad en el contexto
Otras funciones: flush(), refresh(), find()
Fábrica de objetos de consulta
createQuery() : crea un instancia de consulta para utilizar EJB QL
createNamedQuery(): crea una instancia predefinida de consulta
createNativeQuery(). crea instancias de consultas para utilizar SQL
Ciclo de Vida
DEPARTAMENTO DE SISTEMAS
Ciclo de vida (cont.)
DEPARTAMENTO DE SISTEMAS
New Entity
Managed Entity
Tiene entidad persistente
Asociada con un contexto de persistencia
Detached Entity
Creada utilizando “new”
No tiene identidad persistente o estado
Tiene identidad persistente
No está asociada a un contexto de persistencia
Removed Entity
Tiene identidad persistente
Asociada con un contexto de persistencia
Está programada para ser borrada del repositorio de datos
Ejemplo API Entity Manager
DEPARTAMENTO DE SISTEMAS
public Order createNewOrder(Customer customer) {
Order order = new Order(customer);
entityManager.persist(order);
return order;
}
public void removeOrder(Long orderId) {
Order order =
entityManager.find(Order.class, orderId);
entityManager.remove(order);
}
public List findWithName(String name) {
return em.createQuery( "SELECT c
FROM Customer c
WHERE c.name LIKE :custName") .setParameter("custName", name)
.setMaxResults(10) .getResultList();
}
Persistencia
DEPARTAMENTO DE SISTEMAS
Mecanismos de persistencia
La instancia de forma directa utiliza el método persist
Si la instancia está asociada a otra instancia de entidad que invoca el método
persist: si las relaciones de la entidad hacia otras son cascade=PERSIST o ALL.
Llamar al Entity Manager para que persista
LineItem li = new LineItem(...);
order.getLineItems().add(li);
em.persist(li);
return li;
El método persist es propagado a todas las entidades relacionadas al
llamado de la entidad que tienen el elemento cascade en ALL o PERSIST
en la anotación de la relación
Order.java
@OneToMany(cascade=ALL, mappedBy=“order")
public
Collection<LineItem>
getLineItems(){return
lineItems;}
Borrado de entidades
DEPARTAMENTO DE SISTEMAS
Encontrar la entidad
Llamar el método remove sobre el
EntityManager
Order order = em.find(...);
em.remove(order);
Al igual que para la creación, la operación de
borrado es propagada
Sincronización del estado
DEPARTAMENTO DE SISTEMAS
El estado de una instancia es sincronizado con la
base de datos cuando la transacción asociada a la
entidad hace commit
Si una instancia administrada está en una relación
bidireccional con otra instancia administrada, la
información será persistida basada en el lado dueño
de la relación
Para forzar la sincronización de la entidad con la
base de datos se puede invocar el método flush
Consulta de entidades
DEPARTAMENTO DE SISTEMAS
createQuery
em.createQuery("SELECT c FROM Customer c WHERE c.name
LIKE :custName")
.setParameter("custName", name) .setMaxResults
(10).getResultList();
createNamedQuery
Declaración
@NamedQueries( value={@NamedQuery
(name="findAllCustomersWithName",
query="SELECT c FROM Customer c WHERE c.name
LIKE :custName" ),
Uso
em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith")
.getResultList();
Tipos de Entity Manager
DEPARTAMENTO DE SISTEMAS
Container-Managed Entity Managers:
el ciclo de vida del entityManager es manejado por el
contenedor, el contexto es propagado automáticamente a
todos los componentes de la aplicación que usan la instancia
en una transacción
@PersistentContext
EntityManager em;
Application-Managed Entity Managers:
el ciclo de vida del entityManager es manejado por la
aplicación
el contexto no es propagado a los otros componentes
@PersistentUnit
EntityManagerFactory emf;
EntityManager em = emf.createEntityManager()
Agenda
DEPARTAMENTO DE SISTEMAS
Generalidades de las entidades JEE
Mapeo con la BD
Administración de Entidades
Apoyo al desarrollo de aplicaciones
Configuración
Unidades de Persistencia
DEPARTAMENTO DE SISTEMAS
Conjunto de todas las clases administradas por el
EntityManager instances en la aplicación
Definidas en el archivo de configuración persistence.xml
Pueden ser empacadas como parte de un EJB JAR file, o
como un JAR incluido en un WAR o EAR.
Estas unidades son copiadas al contenedor para ser
desplegadas (deployed)
Unidades de Persistencia (cont)
DEPARTAMENTO DE SISTEMAS
persistence.xml define una o más
unidades de persistencia.
Depende de un DataSource
Unidades de Persistencia (cont)
DEPARTAMENTO DE SISTEMAS
Datasource: Define un pool de
conexiones (p.e. a una BD )
Agenda
DEPARTAMENTO DE SISTEMAS
Generalidades de las entidades JEE
Mapeo con la BD
Administración de Entidades
Configuración
Apoyo al desarrollo de aplicaciones
Helpers
Listener
Finders
Clases de Ayuda (Helpers)
DEPARTAMENTO DE SISTEMAS
Una entidad puede tener clases de ayuda para
Implementar métodos de callback (Listener)
Declarar los queries estáticos sobre la entidad
usando anotaciones (Finder)
Ofrecer clases simples para pasar a las capas de
usuario (Business Objects)
Listener
DEPARTAMENTO DE SISTEMAS
Los métodos de callback permiten
tener mayor control sobre el ciclo de vida de la entidad, por
parte del desarrollador
recibir notificaciones sobre hechos ocurridos sobre un objeto:
carga, borrado o salvado
El listener de una entidad implementa los métodos de callback
Cada método de callback viene con la anotación que declara
qué solicitud atenderá
@prePersist
public void doPrePersist ( );
Listener (cont.)
DEPARTAMENTO DE SISTEMAS
PrePersist, PreRemove: invocados por el EntityManager antes
de hacer persistir o eliminar la instancia y son sincrónicos.
PostPersist, PostRemove: Invocados por el EntityManager
después de que se han ejecutado los métodos de persistencia
o eliminación de la instancia.
PreUpdate, PostUpdate: Son invocados antes y después de las
operaciones de actualización de la instancia del bean de
entidad.
PostLoad: Es invocado después de que la instancia de la
entidad ha sido cargada en el contexto de persistencia que le
corresponde.
Listener (cont.)
DEPARTAMENTO DE SISTEMAS
El listener de una entidad es declarado
usando la anotación ‘@EntityListener’
@Entity
@EntityListeners(<ListenerClass>)
public class miEntidadBean ...
Finders
DEPARTAMENTO DE SISTEMAS
Una clase Finder declara en anotaciones los named
queries de una entidad
@NamedQuery (
Name=”findMiEntidadByXX”
queryString=”SELECT … FROM …”
) ...
public class miEntidadFinderServices extends
miEntidadBean
{
}
Por problemas de la versión actual de Jboss
incluiremos los Finders en la misma clase de la
entidad
Value Objects
DEPARTAMENTO DE SISTEMAS
POJOs
Tienen los mismos atributos que la clase de entidad
Ofrecen métodos get y set para cada atributo, no tienen
NINGUNA lógica de negocio
Son el tipo de objetos que se debe pasar entre las capas, an
particular a la capa web solo deben llegar este tipo de objetos
para presentar los datos al usuario
Resumen de Patrones
DEPARTAMENTO DE SISTEMAS
Contenedor Web
Business
Objects
Business Objects
Delegado de
Negocios
(Helper)
Filtros
Value
List
Fachada
Controlador
Vistas
Contenedor EJB
Entidades
Business Objects
DAO
Este material fue preparado por
DEPARTAMENTO DE SISTEMAS
Nicolás López
Pilar Villamil
Darío Correal
Referencias
DEPARTAMENTO DE SISTEMAS
http://java.sun.com/javaee/5/docs/tutorial/doc/
http://www.jcp.org/en/jsr/detail?id=220
http://www.labo-sun.com/resource-fressentiels-836-4-java-j2ee-ejb-3-les-entreprise-javabean-version-3-javabeans-.htm
http://www.solarmetric.com/resources/ejb-apiquickref.pdf
0
Puede agregar este documento a su colección de estudio (s)
Iniciar sesión Disponible sólo para usuarios autorizadosPuede agregar este documento a su lista guardada
Iniciar sesión Disponible sólo para usuarios autorizados(Para quejas, use otra forma )