Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Informacin 2
Java Persistence API
El concepto de persistencia
En Java manipulamos objetos, los cuales son instancias de clases
Los objetos tienen referencias a otros objetos o a colecciones de los
mismos
En forma recursiva pueden referenciarse a si mismos
Los objetos encapsulan datos y comportamiento
El problema es que este estado es accesible solo mientras la JVM
esta ejecutando
Si la JVM se detiene o si el garbage collector destruye un objeto, este estado
desaparece
Algunos objetos necesitan que sus datos perduren la vida de la JVM
El concepto de persistencia
Un objeto que puede almacenar su estado en un medio permanente
y durable, se dice que es un objeto persistente
En las aplicaciones empresariales, el estado persistente suele
almacenarse en bases de datos relacionales
Existen diversos mecanismos para lograr este objetivo
Utilizar mecanismos manuales basados en JDBC
Realizar un mapeo automtico entre instancias de clases y tuplas de una base
de datos, a travs de un ORM
JPA es la especificacin de una solucin de ORM para la plataforma
Java EE
Entidades
Cuando decimos que un objeto se mapea en una tabla de una base
de datos relacional, se utiliza el termino ENTIDAD en lugar de OBJETO
Los objetos son instancias que solo viven en memoria
Las entidades son objetos que viven corto tiempo en memoria, pero
son persistentes en la base de datos
Entidades
Tienen la habilidad de ser mapeadas a la base de datos
Pueden ser concretas o abstractas
Soportan herencia y relaciones
Una vez que una entidad es mapeada a la base de datos, puede ser
gestionada por JPA
Podemos persistir, eliminar y consultar una entidad de la base de
datos
Entidades
En el mundo JPA, es un POJO
Tienen metadatos
Manejan estado, el cual puede ser accedido por getters y modificado
por setters
El estado de la entidad esta representado por los valores de los
atributos de la misma
OBJETO
ENTIDAD
Entidades
Estn anotadas con:
@javax.persistence.Entity
Debemos marcar un atributo como clave primaria, usando la
anotacin:
@javax.persistence.Id
Debe tener un constructor por defecto (publico o protected)
Debe ser una clase top-level (no puede interfaz o enumerado)
Entidades
La clase no puede estar marcada con final
Ningn mtodo o atributo de la clase puede estar marcado con final
Si la entidad debe ser pasada como parmetro a travs de una
interfaz remota, entonces debe implementar la interfaz
java.io.Serializable
Object-Relational Mapping
A travs del uso de metadatos (XML o anotaciones), JPA puede
mapear las entidades en la base de datos
Un proveedor de persistencia (implementacin de JPA) es el
encargado de usar estos metadatos para sincronizar el estado entre
los atributos de la entidad y la tabla
Proveedor de
persistencia
Manipulando entidades
Una vez que tenemos las entidades mapeadas, podemos utilizar JPA
para acceder a las entidades
Podemos consultar entidades y sus relaciones, SIN CONOCER la
estructura de la base subyacente
El elemento central de JPA que permite realizar esto, es el API:
javax.persistence.EntityManager
Manipulando entidades
El rol del EntityManager es
Gestionar entidades
Leer y escribir de una base de datos
Permitir operaciones CRUD simples
Permitir consultar complejas usando JPQL
Es una interfaz cuya implementacin la brinda un proveedor de
persistencia
Manipulando entidades
Por ejemplo, podemos usar el EntityManager de esta forma:
Manipulando entidades
Extendemos la entidad
Persistence Unit
Algo que nos falta en los cdigos anteriores es:
A que base de datos nos conectamos?
Como nos conectamos?
Cual es servidor, puerto y nombre de la base?
Con que usuario nos conectamos?
Que driver JDBC vamos a utilizar?
Esta informacin se encuentra en un elemento denominado
Persistence Unit
Persistence Unit
Cuando se crea el EntityManagerFactory, el nombre de la unidad de
persistencia se le pasa como parmetro
PERSISTENCE_CONTEXT_NAME
La informacin a utilizar para establecer la conexin, se coloca en el
archivo persistence.xml, en el classpath del modulo, dentro del
directorio META-INF
Ciclo de vida de una entidad
Bean Validation
Adems de la validacin manual (a travs de un Validator), es posible
utilizar Bean Validation automticamente en una entidad JPA
Las constraints pueden ser aplicadas en clases de entidad, clases
embeddable y mapped superclases
La validacin ocurre automticamente siempre luego de los eventos
PrePersist
PreUpdate
PreRemove
ORM
Para establecer el vinculo entre las entidades en el mundo Java y los
elementos a nivel relacional, debemos definir las anotaciones de
ORM para la entidad
JPA utiliza configuracin por excepcin
A menos que especifiquemos lo contrario, se asumen valores por
defecto
En ciertas situaciones, esto no nos sirve (ej. acceder a un esquema
legado)
@Table
Por defecto el nombre de la tabla y la entidad coinciden
Para configurar esto, debemos usar la anotacin
@javax.persistence.Table
El elemento mas bsico que podemos cambiar es el nombre de la
tabla
@Table(name = "t_book")
Podemos especificar el schema y el catalog de la tabla
@SecondaryTable
Permite colocar los datos de una entidad, en una tabla y N tablas
secundarias subordinadas
Podemos especificar una @SecondaryTable o un conjunto de tablas,
usando @SecondaryTables
Para cada atributo, usando @Column, podemos especificar a que
tabla pertenece
@SecondaryTable
Debemos tener cuidado con este tipo de tablas y la performance
Cuando queremos acceder a los atributos de una entidad, vamos a
tener que realizar un join entre las tablas involucradas
Pueden ser una buena alternativa cuando tenemos atributos costosos
(BLOBs) que queremos aislar en tablas especificas
Primary Keys
Identifican unvocamente una tupla en una tabla en la base de datos
Puede ser una columna o un conjunto de columnas
JPA requiere que las entidades tengan un identificador mapeado a
una clave primaria
Una vez actualizado (en la base), el valor de una clave primaria no
puede ser actualizado
@Id / @GeneratedValue
@Id es utilizado para denotar un atributo simple que se mapea a la
clave primaria
Puede ser del siguiente tipo:
Primitivo: byte, int, short, long, char
Wrapper: Byte, Integer, Short, Long, Character
Arrays de primitivos/wrappers: int[], Integer[]
Strings, numeros y fechas: String, BigInteger, Date
@Id / @GeneratedValue
El valor de la clave primaria puede ser asignado en forma manual o
ser generado automticamente
Para esto usamos la anotacin @GeneratedValue, que puede tomar
cuatro valores posibles
SEQUENCE , IDENTITY, TABLE, AUTO
El valor por defecto es AUTO
Campos Identity
La base debe soportar columnas de tipo autogeneradas, como SQL
Server y MySQL
Debemos hacer
Tabla
Podemos generar los valores de clave primaria a travs de una tabla e
la propia base de datos
Esta tabla contendr una fila por cada entidad que necesite generar
valores de clave primaria
Podemos usar los valores por defecto o utilizar una tabla ya creada
Tabla
Para mapear a una tabla existente, usamos un TableGenerator
Tabla
La tabla generada en este caso se mapea a la siguiente estructura
Estrategia por defecto
Cuando especificamos que la estrategia es AUTO, estamos indicando
que el proveedor de persistencia puede seleccionar la estrategia que
crea conveniente
Generalmente la seleccin es TABLE, ya que es el mecanismo
garantizado para cualquier manejador de base de datos
En el caso de utilizar Hibernate como proveedor de persistencia, el
nombre de la tabla por defecto, es hibernate_sequences
Primary Keys compuestas
Cuando se mapean las entidades, es una buena practica:
Usar una nica columna como clave
Que esta columna sea de un tipo integral (INTEGER, LONG, etc.)
A veces esto no es posible
Si tengo que adherir la clave a ciertas reglas de negocio
Si tengo que mapear un esquema legado
Tenemos dos posibilidades, @EmbeddedId o @IdClass.
@Embedded
La anotacin @Embedded representa objetos que sern embebidos
dentro de otros objetos
Un objeto embebido no tiene identidad (no tiene PK por si mismo)
Sus atributos terminaran formando parte de las columnas de la tabla
que contiene el objeto embebido
@Embedded
Un objeto de este tipo debe:
Tener un constructor sin parmetros
Debe tener getters y setters para los atributos all presentes
Debe definir el mtodo equals y el mtodo hashCode
La clase no tiene una identificacin por si misma, esto es, no tiene atributos
marcados con @Id
@Embedded
@EmbeddedId
Esta anotacin se utiliza
cuando representamos los
campos de una clave
compuesta a travs de un
@Embedded
En este caso, no
necesitamos indicar la clave
primaria con @Id
@EmbeddedId
En este caso, la clave primaria no es un atributo simple, sino que esta
representada por una instancia del objeto embebido
Para utilizarla, debemos hacer:
@IdClass
Es parecido al mecanismo anterior, pero los atributos que componen
la clave primaria, deben especificarse en la clase utilizando @Id (por
separado)
@IdClass
Luego, en la clase indicamos cual es la clase que representa los
valores de clave primaria
Atributos
Componen el estado de la entidad
Entre otros, podemos mapear los siguientes tipos:
Primitivos y sus correspondientes wrappers
Arrays de bytes y chars
Strings, tipos numricos y tipos temporales
Tipos enumerados
Tipos que implementen Serializable
Colecciones de tipos bsicos y embeddables
Atributos
Una entidad tambin puede tener atributos
De tipo entidad
Colecciones de entidades
Clases embebidas
Estos tipos de atributos, requieren el uso de relaciones entre
entidades
Como con los nombres de tablas, se utiliza configuracin por
excepcin
@Basic
Es la anotacin mas simple para mapear un campo a la base de datos
Permite hace un override a la forma en como se levantan los datos de
la base
@Basic
optional
Permite indicar si el atributo puede o no ser nulo
No aplica para tipos de datos primitivos
fetch
Puede tomar dos valores: LAZY o EAGER
Le indica al provider cuando debe cargar el dato en cuestin
EAGER: Cuando se carga la entidad
LAZY: Cuando se accede al atributo
@Column
@Column
Un aspecto importante se da cuando tenemos un atributo con
Una validacin B.V. del tipo @NotNull
Un mapeo @Column con el atributo nullable en false
La primera aplica en el espacio de Java
La segunda aplica en el espacio de la base de datos
@Temporal
Los tipos de datos Date (java.sql y java.util) puede ser llevados a la
base a diferentes representaciones
Para controlar esto, usamos la anotacin @Temporal, que puede
tomar tres valores
DATE: Solo se almacena la fecha
TIME: Solo se almacena la hora
TIMESTAMP: Se almacena fecha y hora completa
@Transient
En JPA, cuando anotamos la clase con @Entity, esto hace que todos
sus campos formen parte del estado persistente
Si no queremos persistir un atributo de una entidad, podemos:
Colocarle la anotacin @Transient
Colocarle el modificador de acceso transient al atributo
@Enumerated
Los valores de un enumerado son constantes, que tienen implcito un
ordinal, el cual depende del orden en el que fueron declarados
En la base de datos, podemos almacenas la constante (como string) o
el ordinal del enumerado
@Enumerated
@Enumerated acepta dos posibles valores
EnumType.STRING para indicar que se quiere guardar el nombre de la
constante del valor del enumerado
EnumType.ORDINAL para indicar que se quiere guardar el ordinal del valor del
enumerado
ORDINAL es el valor por defecto
Embeddables
Tienen 2 partes
La clase que se embebe
La clase que embebe a la primera
En el primer caso se usa la anotacin @Embeddable para indicar que
es un objeto que puede ser embebido dentro de otro
En el segundo caso, se usa la anotacin @Embedded para indicar que
estamos colocando un objeto embebible all
Relaciones entre objetos
Representa un vinculo entre dos entidades
Tienen direccin
Puede ser unidireccionales o bidireccionales
Relaciones entre objetos
Tienen cardinalidad
Esto refiere a la cantidad de participantes en cada extremo de la relacin
Relaciones en la base
Pueden ser establecidas con columnas de join (foreign keys)
Relaciones en la base
O pueden ser establecidas por tablas de mapeo
Relaciones entre entidades
Relaciones entre entidades
Customer y Address tienen una relacin unidireccional
Relaciones entre entidades
Customer y Address tienen una relacin bidireccional
CUIDADO
Lo anterior, NO ES exactamente igual a esto
@OneToOne
En estos casos, se tiene una referencia a un elemento
@OneToOne
@JoinColumn
Es similar a @Column, solo que es utilizada para customizar la
columna de foreign key
Siempre debe utilizarse en el lado dueo de la relacin (el que no
contiene mappedBy)
En el caso anterior, no tenemos lado mappedBy, solamente uno,
debido a que es unidireccional
@OneToMany unidireccional
En este caso, el objeto origen mantiene una coleccin de objetos
destino
@OneToMany unidireccional
Este tipo de relaciones en JPA, generan una tabla intermedia de
mapeo entre ambas entidades
@JoinTable
Podemos usar esta anotacin para customizar la tabla de mapeo
entre ambas entidades
@JoinTable
La tabla obtenida, en este caso cambia a lo siguiente:
@OneToMany unidireccional
Para relaciones de este estilo, la accin por defecto es usar una tabla
de mapeo
Sin embargo, es posible modificar esto para utilizar una columna de
join en la tabla subordinada
Basta indicar en la entidad padre, que vamos a utilizar una
@JoinColumn en lugar de @JoinTable
@OneToMany unidireccional
En este caso, la tabla de mapeo queda de la siguiente forma:
@OneToMany bidireccional
Para transformar esta relacin en bidireccional, en realidad debemos
hacer que la lnea de la orden referencia a la orden
Para esto, agregamos una referencia a la orden y utilizamos la
anotacin @ManyToOne
Es importante en este caso, que la anotacin tenga el atributo
mappedBy para indicar que es la inversa de la anterior
@ManyToMany bidireccional
@ManyToMany bidireccional
Las tablas obtenidas en estos casos son las siguientes:
Fetching
Todas las anotaciones definen un mecanismo de fetching
(recuperacin de datos)
Los objetos asociados pueden ser cargados:
Inmediatamente: FetchType.EAGER
Cuando se requieran: FetchType.LAZY
Fetching
Por ejemplo, en esta situacin:
SELECT b
FROM Book b