You are on page 1of 36

JPA

Java Persistence API (JPA) proporciona un modelo de persistencia basado en POJO"s para mapear bases de datos relacionales en Java. El Java Persistence API fue desarrollado por el grupo de expertos de EJB 3.0, aunque su uso no se limita a los componentes software EJB. También puede utilizarse directamente en aplicaciones web y aplicaciones clientes; incluso fuera de la plataforma Java EE, por ejemplo, en aplicaciones Java SE. En su definición, se han combinado ideas y conceptos de los principales frameworks de persistencia como Hibernate, Toplink y JDO, y de las versiones anteriores de EJB. Todos estos cuentan actualmente con una implementación JPA. El mapeo objeto/relacional, es decir, la relación entre entidades Java y tablas de la base de datos, se realiza mediante anotaciones en las propias clases de entidad, por lo que no se requieren ficheros descriptores XML. También pueden definirse transacciones como anotaciones JPA. Java Persistence API consta de tres áreas:  El Java Persistence API  El lenguaje de query  El mapeo de los metadatos objeto/relacional Basicamente JPA es una API para ORMs (Object-Relational mapping), el cual permite:  Abstraer del proveedor de persistencias, que no es mas que la implementacion que se use. Por ejemplo puede utilizar Hibernate, Toplink, JDO y otros utilizando la misma API (al estilo de JDBC y los drives para cada BD)  Eliminar la necesidad de escribir el SQL que mapea la base de datos a los objetos utilizando simples anotaciones. Ya no se escribiran líneas sql en los programas, sino que se realizaran consultas sobre los objetos.  Poder crear relaciones muchos a uno, uno a uno, uno a muchos y muchos a muchos entre cualquier cantidad de objetos que se quieras una vez mas solo con anotaciones  Controlar la transaccionalidad (utilizando JTA o JDBC) de las consultas y demás. Obviamente ayuda mucho con el tema de la concurrencia y en la forma en que se gestiona  Tiene un cache de primer nivel que por defecto evita estar viendo a la BD muchas veces para lo mismo en una misma transaccion.  Puede utilizar un cache de segundo nivel que incrementara en gran mayoria el rendimiento de la aplicacion y la escalabildidad

 Trae un lenguaje de consultas OO facil de usar que permite hacer navegacion entre tablas como si fueran objetos.  por ejemplo, where empresa.ciudad.pais.nombre = "El Salvador" donde empresa ciudad y pais son tres tablas diferentes y nombre es una propiedad de Pais. Requisitos de una Entity JPA  Se anotan con @Entity  Tienen una propiedad anotada con @Id  Constructor sin argumentos public/protected  No puede ser final  Puede extender de otra  Puede ser abstracta  Es un POJO (Plain Old Java Objects), objeto liviano que no implementan ninguna interfaz INCO - Facultad de Ingeniería – Montevideo, Uruguay 10 Estado Persistente  Definido por atributos con visibilidad no pública (privada, protegida, o de paquete)  Atributos persistentes o Tipos primitivos o Wrappers de tipos primitivos o Otras entidades o Colecciones INCO - Facultad de Ingeniería – Montevideo, Uruguay 11 Entity JPA - Ejemplo @Entity public class Employee { @Id private int id; private String name; private long salary; public Employee() {} public Employee(int id) { this.id = id; }

public int getId() { return id; } public void setId(int id) { this.id = id; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 12 Entity JPA - Ejemplo public String getName() { return name; } public void setName(String name) { this.name = name; } public long getSalary() { return salary; } public void setSalary (long salary) { this.salary = salary; } } INCO - Facultad de Ingeniería – Montevideo, Uruguay 13 @Table  Es una anotación opcional  Por defecto, la entidad se mapea en el esquema actual, a una tabla con el mismo nombre que la entidad INCO - Facultad de Ingeniería – Montevideo, Uruguay 14 @UniqueConstraints  Permite definir restricciones de integridad sobre la tabla que estamos creando  En general es usada cuando utilizamos la facilidad de auto-creación de esquema @Table(name="CATEGORIES", uniqueConstraints= {@UniqueConstraint( columnNames={"CATEGORY_ID"}) } ) INCO - Facultad de Ingeniería – Montevideo, Uruguay 15 @Column  Mapea una propiedad o campo persistente a una columna de una tabla de la base de

datos @Column(name="USER_ID") protected Long userId; INCO - Facultad de Ingeniería – Montevideo, Uruguay 16 @Column  String name  boolean unique  boolean nullable  String table  length (255) @Column(name=“DESC”, nullable=false, length=512, ... ) private String description; INCO - Facultad de Ingeniería – Montevideo, Uruguay 17 @Enumerated  Permite mapear enumerados en columnas de la base de datos o public enum UserType {SELLER, ADMIN};  Al persistir, tenemos dos opciones o Salvar el ordinal o Salvar el string INCO - Facultad de Ingeniería – Montevideo, Uruguay 18 @Enumerated  Salvamos 0, 1 o @Enumerated(EnumType.ORDINAL) o protected UserType userType;  Salvamos los strings “SELLER” o “ADMIN” o @Enumerated(EnumType.STRING) o protected UserType userType;  Por defecto, se salva el ordinal INCO - Facultad de Ingeniería – Montevideo, Uruguay 19 Tipos de datos temporales

 Las bases de datos hoy día soportan diferentes tipos de datos temporales o DATE o TIME o TIMESTAMP (DATE + TIME)  @Temporal o define contra cual de los tipos anteriores queremos mapear un java.util.Date o un java.util.Calendar INCO - Facultad de Ingeniería – Montevideo, Uruguay 20 Tipos de datos temporales  Usamos el enumerado TemporalType @Temporal(TemporalType.DATE) protected Date creationDate;  Por defecto, se asume TIMESTAMP, el de menor granularidad INCO - Facultad de Ingeniería – Montevideo, Uruguay 21 Tipos de datos temporales  En el caso de los tipos de datos… o java.sql.Data o java.sql.Time o java.sql.TimeStamp …el mapeo es redundante INCO - Facultad de Ingeniería – Montevideo, Uruguay 22 Generación de PKs  Cuando identificamos una columna como PK, lo que le estamos pidiendo a la base es que fuerce unicidad  Las claves primarias que consisten en datos del negocio, se denominan natural keys  Un ejemplo de esto, es el número de cédula de identidad INCO - Facultad de Ingeniería – Montevideo, Uruguay 23 Generación de PKs

 Claves de la forma CATEGORY_ID, USER_ID se denominan surrogate keys  Estas últimas son muy populares, por su facilidad de autogeneración  En sistemas que utilizan frameworks de persistencia, son altamente recomendadas INCO - Facultad de Ingeniería – Montevideo, Uruguay 24 Generación de PKs  Existen tres formas populares de generar claves primarias o A través de campos identity o A través de secuencias o Utilizando una tabla numeradora  Cualquiera de los tres mecanismos se soportan a través de la anotación @GeneratedValue INCO - Facultad de Ingeniería – Montevideo, Uruguay 25 Identities  Muchas bases de datos soportan el tipo de datos IDENTITY  En el caso del usuario, podemos generar la PK de esta forma: @Id @GeneratedValue(strategy= GenerationType.IDENTITY ) @Column(name="USER_ID") protected Long userId; INCO - Facultad de Ingeniería – Montevideo, Uruguay 26 Identities  Cuidado …  En general este valor es obtenido una vez que el registro es “commiteado” en la base  Tener en cuenta que no siempre estará

disponible en el programa INCO - Facultad de Ingeniería – Montevideo, Uruguay 27 Sequences  En este caso, se necesita un generador para la clave primaria  Las secuencias de la BD cumplen ese rol  Por ejemplo, una secuencia Oracle se puede declarar de esta forma: CREATE SEQUENCE USER_SEQUENCE START WITH 1 INCREMENT BY 10; INCO - Facultad de Ingeniería – Montevideo, Uruguay 28 @SequenceGenerator  La utilizamos para declarar un generador asociado a la secuencia @SequenceGenerator( name="USER_SEQUENCE_GENERATOR", sequenceName="USER_SEQUENCE", initialValue=1, allocationSize=10 ) INCO - Facultad de Ingeniería – Montevideo, Uruguay 29 Sequence Generator  En la entidad que utiliza el generador, podemos generar la clave de esta forma: @Id @GeneratedValue( strategy=GenerationType.SEQUENCE, generator="USER_SEQUENCE_GENERATOR") @Column(name="USER_ID") protected Long userId; INCO - Facultad de Ingeniería – Montevideo, Uruguay 30 Table Generator  Es muy similar al caso anterior, solo que los

valores salen de una tabla numeradora, con un formato similar a este: CREATE TABLE SEQUENCE_GENERATOR_TABLE ( SEQUENCE_NAME VARCHAR2(80) NOT NULL, SEQUENCE_VALUE NUMBER(15) NOT NULL, PRIMARY KEY (SEQUENCE_NAME) ); INCO - Facultad de Ingeniería – Montevideo, Uruguay 31 Table Generator  Luego, debemos preparar la tabla para insertar el primer valor de la secuencia INSERT INTO SEQUENCE_GENERATOR_TABLE (SEQUENCE_NAME, SEQUENCE_VALUE) VALUES ('USER_SEQUENCE', 1); INCO - Facultad de Ingeniería – Montevideo, Uruguay 32 Table Generator  Luego, configuramos el TableGenerator en el código @TableGenerator ( name="USER_TABLE_GENERATOR", table="SEQUENCE_GENERATOR_TABLE", pkColumnName="SEQUENCE_NAME", valueColumnName="SEQUENCE_VALUE", pkColumnValue="USER_SEQUENCE“ ) INCO - Facultad de Ingeniería – Montevideo, Uruguay 33 Table Generator  Por último, referenciamos este generador desde la entidad @Id @GeneratedValue( strategy=GenerationType.TABLE, generator="USER_TABLE_GENERATOR")

@Column(name="USER_ID") protected Long userId; INCO - Facultad de Ingeniería – Montevideo, Uruguay 34 Estrategia por defecto  La última opción para la estrategia de generación, es dejar que el provider de base de datos decida la mejor alternativa @Id @GeneratedValue( strategy=GenerationType.AUTO) @Column(name="USER_ID") protected Long userId;

Herencia  Entidades Concretas (hojas)  Entidades Abstractas: definen estado y comportamiento a heredar por las subclases – No anotada: define estado persistente y puede participar en queries y relaciones con entidades – Anotada con @MappedSuperclass: define estado persistente ; no participa en queries ni en relaciones con entidades  Transient Classes: no definen estado persistente; pueden ser heredadas INCO - Facultad de Ingeniería – Montevideo, Uruguay 43 Herencia INCO - Facultad de Ingeniería – Montevideo, Uruguay 44 Herencia @Entity public class Employee { @Id private int id; private String name; @Temporal(TemporalType.DATE)

@Column(name="S_DATE") private Date startDate; // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 45 Herencia @Entity public class ContractEmployee extends Employee { @Column(name="D_RATE") private int dailyRate; private int term; // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 46 @MappedSuperclass public abstract class CompanyEmployee extends Employee { private int vacation; // ... } @Entity public class PartTimeEmployee extends CompanyEmployee { @Column(name="H_RATE") private float hourlyRate; // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 47 Herencia @MappedSuperclass public abstract class CompanyEmployee extends Employee { private int vacation;

// ... } @Entity public class FullTimeEmployee extends CompanyEmployee { private long salary; private long pension; // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 48 Transient Classes public abstract class CachedEntity { private long createTime; public CachedEntity() { createTime = System.currentTimeMillis(); } public long getCacheAge() { return System.currentTimeMillis() -createTime; } } INCO - Facultad de Ingeniería – Montevideo, Uruguay 49 Transient Classes @Entity public class Employee extends CachedEntity { public Employee() { super(); } // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 50 Mapeo de Herencia  Estrategia Single-Table  Estrategia Joined

 Estrategia Table-per-Concrete-Class INCO - Facultad de Ingeniería – Montevideo, Uruguay 51 Estrategia Single-Table  Una sola tabla para guardar instancias de todas las entidades concretas  Se diferencian por un campo discriminador  Eficiente (no requiere join)  Gran cantidad de valores nulos (una entidad utiliza sólo sus atributos) INCO - Facultad de Ingeniería – Montevideo, Uruguay 52 Estrategia Single-Table @Entity @Table(name="EMP") @Inheritance @DiscriminatorColumn(name="EMP_TYPE") public abstract class Employee { ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 53 Estrategia Single-Table @MappedSuperclass public abstract class CompanyEmployee extends Employee { ... } @Entity @DiscriminatorValue("FTEmp") public class FullTimeEmployee extends CompanyEmployee { ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 54 Estrategia Single-Table INCO - Facultad de Ingeniería – Montevideo, Uruguay 55 Estrategia Joined  Cada entidad de la jerarquía tiene una tabla asociada  Refleja la jerarquía  Guarda los datos en forma normalizada sin desperdiciar espacio

 Una instancia de entidad se guarda en múltiples tablas  Requiere joins para obtener una instancia de una entidad concreta INCO - Facultad de Ingeniería – Montevideo, Uruguay 56 Estrategia Joined INCO - Facultad de Ingeniería – Montevideo, Uruguay 57 Estrategia Joined @Entity @Table(name="EMP") @Inheritance(strategy=InheritanceType.JOINED) @DiscriminatorColumn(name="EMP_TYPE", discriminatorType=DiscriminatorType.INTEGER) public abstract class Employee { ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 58 Estrategia Joined @Entity @Table(name="CONTRACT_EMP") @DiscriminatorValue("1") public class ContractEmployee extends Employee { ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 59 Estrategia Joined @MappedSuperclass public abstract class CompanyEmployee extends Employee { ... } @Entity @Table(name="FT_EMP") @DiscriminatorValue("2") public class FullTimeEmployee extends CompanyEmployee { ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 60 Estrategia Joined @Entity

@Table(name="PT_EMP") @DiscriminatorValue("3") public class PartTimeEmployee extends CompanyEmployee { ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 61 Estrategia Table-per-Concrete-Class  Una tabla por cada clase no abstracta  Las propiedades heredadas se repiten en cada tabla  Se evita la redundancia y también se evitan todos los joins a nivel de base de datos  Mapeo o En la clase raíz añadir @DiscriminatorColumn o En cada clase hija añadir @DiscriminatorValue INCO - Facultad de Ingeniería – Montevideo, Uruguay 62 Estrategia Table-per-Concrete-Class INCO - Facultad de Ingeniería – Montevideo, Uruguay 63 Estrategia Table-per-Concrete-Class @Entity @Inheritance(strategy= InheritanceType.TABLE_PER_CLASS) public abstract class Employee { @Id private int id; private String name; @Temporal(TemporalType.DATE) @Column(name="S_DATE") private Date startDate; // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 64

Estrategia Table-per-Concrete-Class public class ContractEmployee extends Employee { @Column(name="D_RATE") private int dailyRate; private int term; // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 65 Estrategia Table-per-Concrete-Class @Entity @Table(name="FT_EMP") public class FullTimeEmployee extends CompanyEmployee { private long salary; @Column(name="PENSION") private long pensionContribution; // ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 66 Entity manager  El API del EntityManager es la parte más importante e interesante de JPA  Maneja el ciclo de vida de las entidades  Actúa de puente entre el mundo O.O y el mundo relacional INCO - Facultad de Ingeniería – Montevideo, Uruguay 67 Entity manager – métodos  public void persist(Object entity);  public <T> T merge(T entity);  public void remove(Object entity);  public <T> T find(Class<T> entityClass, Object primaryKey);

 public void flush();  public void setFlushMode(FlushModeType flushMode);  public FlushModeType getFlushMode(); INCO - Facultad de Ingeniería – Montevideo, Uruguay 68 Entity manager – metodos  public void refresh(Object entity);  public Query createQuery(String jpqlString);  public Query createNamedQuery(String name); INCO - Facultad de Ingeniería – Montevideo, Uruguay 69 Ciclo de vida  Por más que anotemos una entidad con @Entity, el EntityManager no sabe nada de estas, hasta que no se asocia la misma con el EntityManager  Esta idea es opuesta a como funciona un MDB o un Session bean  Es más, la idea del EM, es manejar una entidad el menor tiempo posible INCO - Facultad de Ingeniería – Montevideo, Uruguay 70 Ciclo de vida  Una entidad que esta siendo administrada por el EntityManager, se considera managed o attached  Cuando el EntityManager termina de administrar la entidad, decimos que esta en estado detached  Cuando una entidad no pasa por el EntityMangaer, decimos que esta en estado transient INCO - Facultad de Ingeniería – Montevideo, Uruguay 71 Transient entities

 Cuando una entidad es recien creada a traves de new, entonces esta en estado new o transient Bid bid = new Bid(); INCO - Facultad de Ingeniería – Montevideo, Uruguay 72 Managed entities  Una entidad entra a estado managed, cuando es pasada como parámetro a los métodos persist, merge o refresh  También una entidad esta en estado managed cuando es recibida como resultado de un método find INCO - Facultad de Ingeniería – Montevideo, Uruguay 73 Detached entities  Es una entidad que ya no esta asociada a un EntityManager  En este estado, ya no tenemos garantía de que el estado de la entidad se encuentre sincronizado con la base de datos  La acción de perder ese vinculo, se denomina Detachment, la de volver a vincularlo, se denomina Merge INCO - Facultad de Ingeniería – Montevideo, Uruguay 74 Detached entities  Este tipo de estado es importante, ya que es necesario cuando una entidad cruza entre capas de una aplicación INCO - Facultad de Ingeniería – Montevideo, Uruguay 75 Ciclo de vida de la entidad INCO - Facultad de Ingeniería – Montevideo, Uruguay 76 Persistence context  Formalmente, un persistence context es un conjunto de entidades administradas, controladas por un EntityMangager, durante

un persistence scope  El persistence scope, es el tiempo que un conjunto de entidades permanecen administradas INCO - Facultad de Ingeniería – Montevideo, Uruguay 77 Persistence context  Tenemos dos tipos de persistence scopes o Transaction o Extended INCO - Facultad de Ingeniería – Montevideo, Uruguay 78 Transaction-scoped EntityManager  Es un entity manager asociado con persistence scope transaccional  Las entidades “attacheadas” durante la transacción, son automáticamente “desatacheadas” al terminar la misma INCO - Facultad de Ingeniería – Montevideo, Uruguay 79 Extended EntityManager  Un entity manager tiene un tiempo de vida que abarca varias transacciones  Solo puede ser utilizado dentro de un Session Bean stateful, durando tanto como la instancia permanezca activa INCO - Facultad de Ingeniería – Montevideo, Uruguay 80 Persistiendo entidades public Item addItem(String title, String description, byte[] picture, double initialPrice, long sellerId) { Item item = new Item(); item.setTitle(title); item.setDescription(description); item.setPicture(picture); item.setInitialPrice(initialPrice);

INCO - Facultad de Ingeniería – Montevideo, Uruguay 81 Persistiendo entidades … Seller seller = entityManager.find( Seller.class, sellerId); item.setSeller(seller); entityManager.persist(item); return item; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 82 Persistiendo relaciones public User addUser(String username, String email, String creditCardType, String creditCardNumber, Date creditCardExpiration) { User user = new User(); user.setUsername(username); user.setEmail(email); BillingInfo billing = new BillingInfo(); billing.setCreditCardType(creditCardType); INCO - Facultad de Ingeniería – Montevideo, Uruguay 83 Persistiendo relaciones … billing.setCreditCardNumber( creditCardNumber); billing.setCreditCardExpiration( creditCardExpiration); user.setBillingInfo(billing); entityManager.persist(user); return user; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 84 Cascading

 Por defecto, el comportamiento de JPA es de NO persistir entidades relacionadas  En el caso anterior, el BillingInfo no sería insertado automáticamente  Para que esto funcione, debemos modificar el cascading de la relación INCO - Facultad de Ingeniería – Montevideo, Uruguay 85 Cascading  El cascading define como se propaga la operación sobre los elementos relacionados, cuando hacemos una operación en el elemento “padre” public class User { @OneToOne(cascade=CascadeType.PERSIST) public void setBillingInfo( BillingInfo billing) { INCO - Facultad de Ingeniería – Montevideo, Uruguay 86 Cascading  La idea es similar al cascading en base de datos  Por defecto el cascading esta vacío, por lo que no existe propagación de operaciones de persistencia  Los valores posibles salen del enumerado CascadeType o ALL, MERGE, PERSIST, REFRESH, o REMOVE INCO - Facultad de Ingeniería – Montevideo, Uruguay 87 Cascading  Si el cascading no es especificado, entonces deberemos manualmente propagar las operaciones de persistencia  Para esto, en el ejemplo anterior, debemos primero persistir el BillingInfo y luego el User INCO - Facultad de Ingeniería – Montevideo, Uruguay 88

Recuperación por primary key  JPA soporta el método find en el EntityManager  A este método debemos pasarle la clase que estamos buscando, y el valor de la primary key que estamos filtrando Seller seller = entityManager.find( Seller.class, sellerId); INCO - Facultad de Ingeniería – Montevideo, Uruguay 89 Fetch modes  Tenemos dos posibilidades o Eager o Lazy  En el modo Lazy, los datos son cargados de la base de datos en demanda, cuando son utilizados  En el modo Eager, los datos son cargados al levantar la entidad INCO - Facultad de Ingeniería – Montevideo, Uruguay 90 Ejemplo de Fetch mode  A nivel de relación: @ManyToOne(fetch=FetchType.LAZY) public Seller getSeller() { return seller; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 91 Fetch modes por defecto  Por la característica especial de alguna relaciones, el comportamiento por defecto del fetch para relaciones es diferente según el tipo de relación o One-to-one = EAGER o One-to-many = LAZY o Many-to-one = EAGER

o Many-to-many = LAZY INCO - Facultad de Ingeniería – Montevideo, Uruguay 92 Actualizando entidades  Lo interesante de utilizar JPA como mecanismo de ORM, es que todos los detalles de la actualización de entidades persistentes, es transparente  Esto es debido a que los objetos que están asociados al EntitiyManager, son administrados por el mismo, lo que incluyeoperaciones de actualización INCO - Facultad de Ingeniería – Montevideo, Uruguay 93 Actualizando entidades public void calculateCredit(Long sellerId) { PowerSeller seller = entityManager.find( PowerSeller.class, sellerId); seller.setCreditWorth(100); .. código .. seller.setCreditMax(200); .. código .. } INCO - Facultad de Ingeniería – Montevideo, Uruguay 94 Detachment y merge  Si bien una entidad attached es extremadamente útil, es difícil mantenerlas attacheadas todo el tiempo  Un caso típico se da en las aplicaciones web  Es común que las entidades tengan que ser serializadas y enviadas a la capa web  En la capa web, las entidades serán cambiadas, fuera del scope del EntityManager INCO - Facultad de Ingeniería – Montevideo, Uruguay 95 Detachment y merge public Item addItem(String title,

String description, byte[] picture, double initialPrice, long sellerId) { Item item = new Item(); item.setTitle(title); ... entityManager.persist(item); return item; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 96 Detachment y merge  El ítem devuelto por el método, será enviado a presentación (web), donde puede ser modificado  En algún momento, necesitamos asociar este elemento con la base de datos nuevamente, para sincronizar su estado  Para esto usamos el método merge INCO - Facultad de Ingeniería – Montevideo, Uruguay 97 Detachment y merge INCO - Facultad de Ingeniería – Montevideo, Uruguay 98 Detachment y merge  merge nos garantiza que el objeto está asociado nuevamente con el persistence context, y que eventualmente será sincronizado con la base de datos public Item updateItem(Item item) { entityManager.merge(item); return item; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 99 Detachment y merge  Cuando el método updateItem termine, la base de datos será actualizada con el estado del ítem

 El método merge solo puede ser usado para entidades que existan en la base de datos  Si tratamos de mergear un elemento no existente, se producirá una IllegalArgumentException. INCO - Facultad de Ingeniería – Montevideo, Uruguay 100 Borrado de entidades  Utilizamos el método remove del entity manager  El único detalle de este método, es que solo pueden eliminarse entidades que han sido “mergeadas” con el persistence context public void deleteItem(Item item) { entityManager.remove( entityManager.merge(item)); } INCO - Facultad de Ingeniería – Montevideo, Uruguay 101 Refresh de entidades  Permite cargar los datos de una entidad, desde la base de datos  No es muy común de usar, aunque a veces puede ser útil para deshacer los cambios en una transacción public Item undoItemChanges(Item item) { entityManager.refresh( entityManager.merge(item)); return item; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 102 Refresh de entidades  Sin embargo, hay un escenario donde es muy útil.  Que pasa si al insertar un registro en la base de datos, la propia base modifica el valor de

algunas columnas a través de un trigger  En este caso, desde Java solo veremos lo insertado, ya que los datos generados por la base no serán cargados INCO - Facultad de Ingeniería – Montevideo, Uruguay 103 Refresh de entidades public Item addItem(String title, String description, byte[] picture, double initialPrice, long sellerId) { Item item = new Item(); item.setTitle(title); ... entityManager.persist(item); entityManager.flush(); entityManager.refresh(item); return item; } INCO - Facultad de Ingeniería – Montevideo, Uruguay 104 Flushing  Las operaciones del EntityManager, como persist, merge y remove, no alteran la base de datos inmediatamente  Principalmente esto se hace por motivos de performance  Las operaciones SQL en modo batch suelen ser mas performantes que las operaciones emitidas de a una por vez INCO - Facultad de Ingeniería – Montevideo, Uruguay 105 Flushing  Las operaciones anteriores (alteraciones de la base) son pospuestas hasta que se flushee el EntityManager  Por defecto, el modo de flush es AUTO  Esto significa que el flush es emitido por el

EntityManager según sea necesario INCO - Facultad de Ingeniería – Montevideo, Uruguay 106 Flushing  El modo de flush lo controlamos utilizando el enumerado FlushModeType  Para efectuar el flush, hacemos: entityManager.setFlushMode( FlushModeType.COMMIT); entityManager.flush(); INCO - Facultad de Ingeniería – Montevideo, Uruguay 107 Entity Manager Persistence Scope Transaction @Stateless public class ProjectServiceBean implements ProjectService { @PersistenceContext( unitName="EmployeeService") EntityManager em; INCO - Facultad de Ingeniería – Montevideo, Uruguay 108 Entity Manager Persistence Scope Transaction public void assignEmployeeToProject( int empId, int projectId) { Project project = em.find(Project.class, projectId); Employee employee = em.find(Employee.class, empId); project.getEmployees().add(employee); employee.getProjects().add(project); } INCO - Facultad de Ingeniería – Montevideo, Uruguay 109 Entity Manager Persistence Scope Extended @Stateful

public class DepartmentManagerBean implements DepartmentManager { @PersistenceContext( unitName="EmployeeService", type=PersistenceContextType.EXTENDED) EntityManager em; Department dept; INCO - Facultad de Ingeniería – Montevideo, Uruguay 110 Entity Manager Persistence Scope Extended public void setName(String name) { dept.setName(name); } public void addEmployee(int empId) { Employee emp = em.find(Employee.class, empId); dept.getEmployees().add(emp); emp.setDepartment(dept); } } INCO - Facultad de Ingeniería – Montevideo, Uruguay 111 Entity Manager Persistence Scope Extended  Que ocurre si en el ejemplo anterior omitimos declarar como EXTENDED el PersistenceContextType ? INCO - Facultad de Ingeniería – Montevideo, Uruguay 112 Entity Manager Persistence Scope Extended o Se asume por defecto PersistenceContextType TRANSACTION o Asumiendo que no hay una transacción activa en el cliente, cada método iniciaría y terminará una transacción (recordar REQUIRED)

o Lo anterior hará que el entity manager use diferentes Persistence Contexts cada vez o Si ya pasamos por el método init, se tendrá una instancia creada de Departament, por lo tanto cada vez que se invoque por ejemplo setName, actuará sobre esta entidad. Y ??? INCO - Facultad de Ingeniería – Montevideo, Uruguay 113 Entity Manager Persistence Scope Extended o Como la ejecución de init terminó su transacción, dejó a la instancia Departament detached o Las sucesivas invocaciones a setName actuarán sobre la misma instancia, cambiando el valor del atributo name o Pero … o Los cambios nunca se impactarán en la base de datos INCO - Facultad de Ingeniería – Montevideo, Uruguay 114 Recuperando información  Con JPA podemos usar los siguientes métodos para recuperar información o El metodo EntityManager.find(…) o Queries escritas en JPQL o Queries nativas escritas en SQL INCO - Facultad de Ingeniería – Montevideo, Uruguay 115 Query API  Los pasos para utilizar una consulta con JPA son los siguientes: o Obtener una referencia al EntityManager o Crear una instancia de una Query o Ejecutar la query o Recuperar los resultados (entities) INCO - Facultad de Ingeniería – Montevideo, Uruguay 116 Queries

 El API de consultas de JPA soporta dos tipos de consultas: o Named o Dynamic INCO - Facultad de Ingeniería – Montevideo, Uruguay 117 Queries  Las Named queries son consultas almacenadas que pueden ser reutilizadas en un programa  Las Dynamic queries son consultas que se forman dinámicamente en el programa  Su estructura se construye programáticamente  En cualquier caso, su uso es similar INCO - Facultad de Ingeniería – Montevideo, Uruguay 118 Queries @PersistenceContext em; ... public List findAllCategories() { Query query = em.createQuery( "SELECT c FROM Category c"); ... return query.getResultList(); } INCO - Facultad de Ingeniería – Montevideo, Uruguay 119 Named Queries  Se crean asociadas a la entidad que queremos consultar  La definición puede ser almacenada en formato XML o en el propio código de la clase  Las named queries deben tener nombre único dentro de una persistence unit INCO - Facultad de Ingeniería – Montevideo, Uruguay 120

Named Queries @Entity @NamedQuery( name = "findAllCategories", query = "SELECT c FROM Category c WHERE c.categoryName LIKE :categoryName ") public class Category implements Serializable { ... } INCO - Facultad de Ingeniería – Montevideo, Uruguay 121 Named Queries @Entity @NamedQueries({ @NamedQuery( name = "findCategoryByName", query = "SELECT c FROM Category c WHERE c.categoryName LIKE :categoryName order by c.categoryId" ), INCO - Facultad de Ingeniería – Montevideo, Uruguay 122 Named Queries @NamedQuery( name = "findCategoryByUser", query = "SELECT c FROM Category c JOIN c.user u WHERE u.userId = ?1“ ) }) @Table(name = "CATEGORIES") public class Category implements Serializable

INCO - Facultad de Ingeniería – Montevideo, Uruguay 123 Creando una instancia de la Query  public Query createQuery(String qlString);  public Query createNamedQuery(String name);  public Query createNativeQuery(String, sqlString); INCO - Facultad de Ingeniería – Montevideo, Uruguay 124 Creando una instancia de la Query  public Query createNativeQuery(String sqlString,Class result-class);  public Query createNativeQuery(String sqlString,String result-setMapping); INCO - Facultad de Ingeniería – Montevideo, Uruguay 125 Creando una instancia de la Query  Algunos ejemplos…  Named o Query query = em.createNamedQuery("findAllCategories");  Dynamic o Query query = em.createQuery("SELECT i FROM Item i"); INCO - Facultad de Ingeniería – Montevideo, Uruguay 126 Utilizando la interfaz Query  Para ejecutar la consulta… query = em.createNamedQuery( "findCategoryByName"); query.setParameter("categoryName", categoryName); query.setMaxResults(10); query.setFirstResult(3); List categories = query.getResultList();

INCO - Facultad de Ingeniería – Montevideo, Uruguay 127 Parámetros en la Query  En una query, podemos usar una cláusula WHERE para restringir los valores obtenidos  Por ejemplo, todos los ítems con un precio determinado, pueden obtenerse así: SELECT i FROM Item i WHERE i.initialPrice = ?1 INCO - Facultad de Ingeniería – Montevideo, Uruguay 128 Parámetros en la Query  En el caso anterior, parametrizamos la consulta utilizando parámetros posicionales  Para establecer el valor del parámetro, basta con hacer: query.setParameter(1,100) INCO - Facultad de Ingeniería – Montevideo, Uruguay 129 Parámetros en la Query  Podemos usar otro tipo de parámetros, llamados parámetros nombrados (named parameters)  Son de la forma: SELECT i FROM Item i WHERE i.initialPrice = :price INCO - Facultad de Ingeniería – Montevideo, Uruguay 130 Parámetros en la Query  Estos mejoran muchísima la legibilidad y búsqueda de errores de una query  Establecer el valor de uno de estos, se realiza de la siguiente forma: query.setParameter(“price”,100) INCO - Facultad de Ingeniería – Montevideo, Uruguay 131 Recuperando una entidad  Si nuestra consulta devuelve una instancia (tupla) resultado, con el método

getSingleResult podemos obtenerla  Produce error si retorna mas de una tupla query.setParameter(1,“Categoria”); Category cat = (Category)query.getSingleResult(); INCO - Facultad de Ingeniería – Montevideo, Uruguay 132 Recuperando una entidad try { ... query.setParameter(1,“Categoria”); Category cat = (Category)query.getSingleResult(); ... }catch (NonUniqueResultException ex) { handleException(ex); } catch (NoResultException ex) { handleException(ex); } INCO - Facultad de Ingeniería – Montevideo, Uruguay 133 Recuperando una colección  La mayoría de las queries retorna mas de una tupla resultado  Para esto, podemos usar el método getResultList() query.setParameter("lowPrice", lowPriceValue); query.setParameter("highPrice", highPriceValue); List items = query.getResultList(); INCO - Facultad de Ingeniería – Montevideo, Uruguay 134 Paginado de resultados  setMaxResults permite definir el máximo numero de entidades que serán traídas en el result set

 setFirstResult permite definir la posición del primer resultado en el result set INCO - Facultad de Ingeniería – Montevideo, Uruguay 135 Paginado de resultados  Por ejemplo para traer los próximos 50 resultados, haríamos: query.setMaxResults(50); query.setFirstResult(50); List items = query.getResultList(); INCO - Facultad de Ingeniería – Montevideo, Uruguay 136 JPQL  El procesador de consultas de JPA, transforma una consulta JPQL en una consulta SQL INCO - Facultad de Ingeniería – Montevideo, Uruguay 137 SELECT  Es de la forma: SELECT c FROM Category c WHERE c.categoryName LIKE :categoryName ORDER BY c.categoryId INCO - Facultad de Ingeniería – Montevideo, Uruguay 138 SELECT  Una consulta puede tener los siguientes elementos: o SELECT o FROM o WHERE o ORDER BY o GROUP BY o HAVING INCO - Facultad de Ingeniería – Montevideo, Uruguay 139 Empaquetado  Se debe definir un descriptor de la unidad de persistencia

o META-INF/persistence.xml  JBoss utiliza Hibernate 3 para implementar JPA <persistence> <persistence-unit name=“tsi2_PU"> <jta-data-source>java:myDS</jta-data-source> <properties> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgtreSQLDialect" /> <property name="hibernate.hbm2ddl.auto" value="update" /> </properties> </persistence-unit> </persistence> INCO - Facultad de Ingeniería – Montevideo, Uruguay 140 Empaquetado  Posibles valores de la propiedad hibernate.hbm2ddl.auto o validate o update o create o create-drop INCO - Facultad de Ingeniería – Montevideo, Uruguay 141 Empaquetado  Dos formas de declarar las entidades que conforman una unidad de persistencia: o Declarando cada una de sus clases o Declarando el nombre de un archivo .jar que contiene las entidades INCO - Facultad de Ingeniería – Montevideo, Uruguay 142 Empaquetado <persistence> <persistence-unit name=“tsi2_PU“> <jta-data-source>java:myDS</jta-data-source>

… <class>tsi2.entities.Cliente</class> <class>tsi2.entities.Empresa</class> </persistence-unit> </persistence> INCO - Facultad de Ingeniería – Montevideo, Uruguay 143 Empaquetado <persistence> <persistence-unit name=“tsi2_PU"> <jta-data-source>java:myDS</jta-data-source> <jar-file>myEntities.jar</jar-file> </persistence-unit> </persistence> INCO - Facultad de Ingeniería – Montevideo, Uruguay 144 Ventajas y Desventajas de JPA  Ventajas o Simplicidad: una única clase para declarar la persistencia (con la ayuda de anotaciones) o Transparencia: las clases a persistir son simples POJOs o No hay restricciones con respecto a relaciones entre objetos (herencia, poliformismo)  Desventajas o Anotaciones (Descripción de la Base de Datos en el código) dificultan el mantenimiento. o Solución: Siempre se puede utilizar un XML