Está en la página 1de 12

Java Persistence API

Taller de Sistemas de Informacin 2


Clase 5a EJB3 JPA (Java Persistence API)

Provee facilidades de mapeo objeto/relacional para poder manipular datos relacionales dentro de programas Java en una modalidad orientada a objetos

Java Persistence API


Compuesta por 6 partes
Requerimientos para los objetos del modelo de dominio Metadatos API Consultas Modelo del ciclo de vida Callbacks

Entidades
Las entidades u objetos del modelo de dominio soportan las tcnicas estndar para el desarrollo de sistemas OO
Herencia Encapsulamiento Polimorfismo

Pueden ser creadas con el operador new, como las clases tradicionales No se requiere una interfaz o superclase especial dentro de EJB3

Entidades

Entidades
Representa un objeto de dominio (liviano) persistente Representa por lo general una tabla en una base de datos relacional Cada instancia de estas entidades, corresponde a una tupla en dicha tabla El artefacto primario de desarrollo de entidades, es la Entity Class
Aunque la Entity Class puede tener Helper Classes

Entidades
El estado persistente de una propiedad, esta representado por campos persistentes o propiedades persistentes Se utilizan annotations de mapeo O/R para mapear entidades y relaciones entre entidades, a elementos de la base de datos relacional

Requerimientos para Entidades


La clase debe estar anotada con la annotation javax.persistence.Entity La clase debe tener un constructor que no reciba argumentos
Puede tener otros constructores

Ni la clase, ni los mtodos, ni los atributos persistentes, pueden ser declarados final Si la clase debe ser utilizada en una interfaz remota, entonces debe ser serializable

Requerimientos para Entidades


Las entidades pueden extender tanto entidades como clases que no son entidades Las clases que no son entidades, tambin pueden extender a las entidades Los atributos persistentes deben ser declarados privados, default o protected
Los usuarios de una entidad, deben acceder a su estado a travs de accessors o mtodos de negocios

Requerimientos para Entidades


Los tipos para los atributos persistentes, deben ser alguno de estos
Tipos primitivos java.lang.String Tipos serializables
Wrappers para tipos primitivos java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp

Requerimientos para Entidades


(Cont.)
Tipos serializables
Tipos definidos por el usuario byte[], Byte[], char[], Character[]

Atributos persistentes
Si la clase utiliza atributos persistentes, entonces el runtime de persistencia accede a los atributos persistentes directamente Los campos anotados con javax.persistence.Transient son ignorados Las anotaciones que mapean con el medio relacional, deben ser aplicadas a todos los campos a persistir

Tipos enumerados Otras entidades o colecciones de entidades Clases embebidas

Propiedades persistentes
Si la clase usa propiedades persistentes, la clase debe seguir la norma utilizada para los JavaBeans
Mtodos get/set, seguidos del nombre de la propiedad con la primer letra en mayscula
Type getProperty() void setProperty(Type type)

Propiedades persistentes
Si los valores son colecciones, entonces deben utilizarse las interfaces de colecciones
java.util.Collection, java.util.Set, java.util.List, java.util.Map

En caso de usar generics, esto debe especificarse en la firma de los mtodos


Set<PhoneNumber> getPhoneNumbers() {} void setPhoneNumbers(Set<PhoneNumber>) {}

Propiedades persistentes
Los tipos de datos primitivos, wrapper y Strings, se mapean a columnas en la base de datos Las relaciones con otras entidades persistentes, deben marcarse explcitamente, mapeandose a claves forneas o tablas de join

Claves primarias
Cada entidad tiene un objeto nico que la identifica Este identificador o primary key sirve para localizar instancias especificas de una entidad Una entidad puede tener claves primarias simples o compuestas Las claves primarias simples, utilizan la anotacin javax.persistence.Id

Claves primarias
Las claves primarias compuestas deben ser declaradas en una primary key class Para este tipo de claves, se utilizan las anotaciones javax.persistence.EmbededId y javax.persistence.IdClass

Claves primarias
Los componentes de una clave primaria debe ser de alguno de los siguientes tipos Java:
Tipos primitivos Wrapper classes java.lang.String java.util.Date java.sql.Date

Primary Key Class


Debe cumplir los siguientes requisitos
La clase debe ser publica Las propiedades deben tener acceso publico o protected La clase debe tener un constructor publico sin argumentos La clase debe implementar los mtodos hashCode() e equals(Object arg) La clase debe ser serializable

Primary Key Class


(Cont.) Debe cumplir los siguientes requisitos
Los campos de una clave primaria (simple o compuesta), deben mapearse con propiedades dentro de la clase de la entidad En este caso, los nombres y tipos de los atributos de la clave primaria, mapeados a la entidad, deben ser iguales

Primary Key Class


public final class LineItemKey implements Serializable { public Integer orderId; public int itemId; public LineItemKey() {} public LineItemKey(Integer orderId, int itemId) { this.orderId = orderId; this.itemId = itemId; } public boolean equals(Object otherOb) { if (this == otherOb) { return true; } if (!(otherOb instanceof LineItemKey)) { return false; } LineItemKey other = (LineItemKey) otherOb; return ((orderId==null?other.orderId==null:orderId.equals (other.orderId)) && (itemId == other.itemId)); } public int hashCode() { return ((orderId==null?0:orderId.hashCode()) ^ ((int) itemId)); } }

Relaciones entre las entidades


Existen cuatro tipos de multiplicidad
one-to-one, one-to-many, many-to-one y many-tomany

One-to-one
Cada instancia de una entidad, esta relacionada con una nica instancia de otra entidad Usan la anotacin javax.persistence.OneToOne en la propiedad o campo que establece la relacin

JPA Metadata
Existen dos tipos de metadata que podemos utilizar en JPA
Logical: Describe el modelo lgico Mapping: Describe como el modelo lgico se mapea con la base de datos subyacente

JPA Metadata
Logical

Usamos Annotations o XML La mayora de los settings tienen valores por defecto inteligentes

JPA Metadata
Logical

JPA Metadata
La ORM Metadata puede ser especificada en annotations o XML El uso de annotations es recomendable en ambientes de desarrollo En ambientes de produccin, el uso de XML es recomendable
El ciclo de vida de la base de datos no tiene porque acompaar el del cdigo El tipo de la base de datos o el esquema de la misma puede variar segn el ambiente (produccin, testing, QA)

JPA Metadata
Mapping

JPA Metadata
Mapping

En el ejemplo anterior, no aparecen las annotations @TABLE o @COLUMN El proveedor de persistencia utiliza valores por defecto para estas propiedades
Para la tabla, el nombre de la clase de la entidad Para los campos, el nombre de las propiedades dentro de la clase de la entidad

@Entity @Table(name="ORDER_TABLE") public class Order { private int id; private String address; @Id @Column(name="ORDER_ID") public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name="SHIPPING_ADDRESS") public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }

Relaciones entre las entidades


One-to-many
Cada instancia de una entidad, esta relacionada con mltiples instancias de otra entidad Usan la anotacin javax.persistence.OneToMany en la propiedad o campo que establece la relacin

Anotaciones

Many-to-one
Mltiples instancias de una entidad, estn relacionadas con una nica instancia de otra entidad Usan la anotacin javax.persistence.ManyToOne en la propiedad o campo que establece la relacin

Relaciones entre las entidades


Many-to-many
Mltiples instancias de una entidad, estn relacionadas con mltiples instancias de otra entidad Usan la anotacin javax.persistence.ManyToMany en la propiedad o campo que establece la relacin

Relaciones entre las entidades


Las relaciones pueden ser bidireccionales o unidireccionales
Las relaciones bidireccionales, tienen un owning side y un inverse side Las relaciones unidireccionales solo tienen un owning side

El owning side determina como el runtime de persistencia actualiza las relaciones en la base de datos

Relaciones entre las entidades


En una relacin bidireccional, cada entidad posee un campo que lo relaciona con la otra entidad
El inverse side de la relacin debe referir a su owning side usando la propiedad mappedBy de las anotaciones OneToOne, OneToMany, ManyToOne y ManyToMany En una relacin, el lado Many siempre es el owning side En relaciones OneToOne, el lado que defina la foreignKey, es el owning side En las ManyToMany, cualquier participante de la relacin puede ser el owning side

Relaciones y Queries
El API de persistencia de Java, utiliza la direccion en la relacin para navegar entre las entidades

APIs
Se basan en las interfaces definidas en el paquete javax.persistence Interfaces clave:
EntityManager Query

Administrando entidades
Las entidades son administradas por el entity manager Esta representado por instancias de javax.persistence.EntityManager Cada una de estas instancias, esta asociada a un persistence context Un persistence context, define el scope bajo el cual las entidades son creadas, persistidas y removidas

En un contexto EJB (Application Server), el EntityManager es:


Inyectado dentro de los EJB Integrado con el contexto transaccional activo

Persistence Context
Es un conjunto de instancias de entidades, administradas, que existen en un data store particular La interfaz EntityManager provee mtodos para interactuar con el pesistence context

Entity Manager
Provee un API para crear y remover instancias de entidades persistentes Provee tambin funcionalidades para localizar por clave primaria un determinada entidad Asimismo, permite realizar queries sobre las entidades

Entity Manager
Container Managed

Entity Manager
Container Managed

El persistence context asociado a las entidades del Entity Manager, es automticamente propagado a todos los componentes que usan dicho EntityManager Todo esto ocurre dentro de una nica transaccin JTA

Para obtener una instancia de un Entity Manager, debemos inyectar este dentro del componente de aplicacin Usamos:
@PersistenceContext EntityManager em;

Entity Manager
Container Managed

Entity Manager
Application Managed

La propagacin automtica del persistence context tiene como ventaja que los componentes de negocio no tienen que hacerlo explcitamente Esto facilita realizar mltiples cambios, en lugares diferentes, pero dentro de la misma transaccin

En este caso, el persistence context no es propagado automticamente a los componentes El ciclo de vida de las instancias de los Entity Managers, es manejado por la aplicacin Las aplicaciones crean instancias de EntityManagers usando el mtodo createEntityManager()

Entity Manager
Application Managed

Algunos ejemplos
Usamos el EntityManager para localizar y crear entidades

Para poder realizar esto, debemos inyectar una referencia a una instancia de la clase EntityManagerFactory
@PersistenceUnit EntityManagerFactory emf; EntityManager em = emf.createEntityManager();

Algunos ejemplos
Usamos el Entity Manager dentro de un Session Bean

Entity Manager
Find

El mtodo find() de EntityManager permite recuperar instancias de entidades


@PersistenceContext EntityManager em; public void enterOrder(int custID, Order newOrder) { Customer cust = em.find(Customer.class, custID); cust.getOrders().add(newOrder); newOrder.setCustomer(cust); }

Java SE
JPA puede ser utilizada dentro de una aplicacin Java SE El nico cuidado a tener es que la creacin e inicializacin debe ser manejada por la aplicacin Las clases e interfaces clave son:
Persistence EntityManagerFactory EntityManager

Java SE

Ciclo de vida
Administramos las instancias de entidades, invocando mtodos sobre la interfaz EntityManager Las instancias de entidades, pueden estar en 4 estados posibles
New Managed Detached Removed

Ciclo de vida
Las entidades new aun no poseen identidad persistente y no estn asociadas a un persistence context Las entidades managed poseen una identidad persistente y estn asociadas a un persistence context

Ciclo de vida
Las entidades detached, poseen una identidad persistente y no estn asociadas a un persistence context Las entidades removed poseen una identidad persistente, estn asociadas a un persistence context y se agendan para eliminar del datastore

Ciclo de vida
Las nuevas instancias de entidades, pueden ser registradas con el EntityManager
Person p = new Person(Pepe, Perez); em.persist(p);

Los registros pueden ser agendados para borrado


em.remove(p.getAddress());

Ciclo de vida
Las instancias de entidades pasan a estado detached cuando el persistence context finaliza Los cambios a las entidades detached, pueden ser combinados en la transaccin actual
void updatePerson(Person personVO) { Person p = em.merge(personVO); p.setLastUpdated(new Date()); }

Callbacks
Como en el caso de los Session Beans y los Message Driven Beans, podemos attachear un EntityListener para capturar ciertos eventos en el ciclo de vida de la entidad
PrePersist: Cuando la aplicacin invoca persist() PostPersist: Luego del INSERT PreRemove: Cuando la aplicacin invoca remove() PostRemove: Luego del DELETE

Callbacks
(Cont.)
PreUpdate: Cuando el container detecta que una entidad esta en estado dirty PostUpdate: Luego del UPDATE PostLoad: Luego de que una instancia fue cargada

Callbacks

Declaramos el listener

Attacheamos un listener a la entidad usando la anotacin @EntityListener

Java Persistence Query Language


El lenguaje de consulta permite definir queries para las entidades y su estado persistente Permite escribir queries portables, independizando del datastore particular

Algunos trminos
Abstract Schema
Es la abstraccion del esquema persistente, sobre el cual las consultas operan El lenguaje de consulta, mapea consultas sobre el Abstract Schema, en consultas sobre el esquema de base de datos

Abstract Schema Type


El abstract schema type de una entidad, se deriva de la clase de la entidad

Algunos trminos
Navigation
Es la accin de atravesar una relacin en una query particular El operador de navegacin es el .

Sintaxis
Una consulta de select tiene 6 elementos
SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY SELECT y FROM son requeridos Los dems son opcionales

Path expression
Una expresin que navega en el estado de la entidad o sus relaciones

State field
Un campo o propiedad persistente de la entidad

La forma general de una consulta de Select es:


QL_statement ::= select_clause from_clause [where_clause][groupby_clause][having_claus e][orderby_clause]

Relationship field
Es un campo que representa una relacin, cuyo tipo corresponde al Abstract Schema Type de la entidad relacionada

10

Sintaxis
La select_clause define el tipo de los objetos o valores devueltos La from_clause define el scope de la query
Define variables de identificacin que pueden ser referenciadas en el SELECT o WHERE

Sintaxis
La where_clause es una expresin que restringe los objetos o valores devuelto por una query group_by, having, order_by tienen la semntica tradicional de SQL

Una variable de identificacin representa:


El abstract schema de una entidad Un elemento de una coleccin que representa una relacin

Sintaxis
Las consultas de delete o update tienen la siguiente forma:
update_statement :: = update_clause [where_clause] delete_statement :: = delete_clause [where_clause]

Ejemplos
Todos los Players
SELECT p FROM Player p

Datos duplicados eliminados


SELECT DISTINCT p FROM Player p WHERE p.position = ?1

La where_clause tiene el mismo significado que en el caso del SELECT

Named parameters
SELECT DISTINCT p FROM Player p WHERE p.position = :position AND p.name = :name

Ejemplos
Queries que navegan a entidades relacionadas
SELECT DISTINCT p FROM Player p, IN(p.teams) t SELECT DISTINCT p FROM Player p JOIN p.teams t SELECT DISTINCT p FROM Player p WHERE p.team IS NOT EMPTY

Ejemplos
Queries que navegan usando relaciones con valores sencillos
SELECT t FROM Team t JOIN t.league l WHERE l.sport = 'soccer' OR l.sport ='football'

Filtrado en los campos relacionados


SELECT DISTINCT p FROM Player p, IN (p.teams) t WHERE t.league.sport = :sport

11

Ejemplos
LIKE
SELECT p FROM Player p WHERE p.name LIKE 'Mich%'

Ejemplos
BETWEEN
SELECT DISTINCT p FROM Player p WHERE p.salary BETWEEN :lowerSalary AND :higherSalary

IS NULL
SELECT t FROM Team t WHERE t.league IS NULL

Operadores de comparacion
SELECT DISTINCT p1 FROM Player p1, Player p2 WHERE p1.salary > p2.salary AND p2.name = :name

IS EMPTY
SELECT p FROM Player p WHERE p.teams IS EMPTY

Creando queries
Utilizamos el EntityManager para crear una consulta
em = emf.createEntityManager(); Query q = em.createQuery(select c from Customer c + where c.name = :name"); q.setParameter("name", "Joe Smith"); Customer c = (Customer)q.getSingleResult(); Collection<Order> orders = c.getOrders(); if (orders == null || orders.size() != 2) { throw new RuntimeException("Unexpected number of orders:" + ((orders == null)? "null" : "" + orders.size())); }

12

También podría gustarte