Jee Ejb

Descargar como ppt, pdf o txt
Descargar como ppt, pdf o txt
Está en la página 1de 127

JEE & EJB 3.

0
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Características principales de EJB 3
 Simplificación del modelo de componentes desde el punto
de vista del desarrollador
 Modelo de componentes menos intrusivo
 Utilización de POJOs como componentes
 Utilización de POJIs como interfaces
 Utilización de anotaciones (metadata)
 Eliminación del uso de los descriptores (opcional)
 Inyección de dependencias (inversión de control)
 Standarización de la API de persistencia para la plataforma
Java (basada en ORMs tales como Hibernate y Toplink)
 Facilitación del testeo de EJBs fuera del container
EJB 3 de capas
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Session beans 2.1
public interface CalculatorRm extends EJBObject
{
public int add(int a, int b) throws RemoteException;
}

public interface CalculatorLc extends EJBLocalObject


{
public int add(int a, int b);
}

public interface CalculatorRmHm extends EJBHome


{
CalculatorRm create() RemoteException, CreateException;
}

public interface CalculatorLcHm extends EJBLocalHome


{
CalculatorLc create() CreateException;
}
Session beans 2.1
public class CalculatorBean implements SessionBean
{
private SessionContext ctx;

public void ejbCreate() {}


public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext pCtx) {this.ctx = pCtx;}
public int add(int a, int b) {return a + b;}
}

<enterprise-beans>
<session>
<ejb-name>CalculatorEJB</ejb-name>
<home>CalculatorRmHm</home>
<remote>CalculatorRm</remote>
<local-home>CalculatorLcHm</local-home>
<local>CalculatorLc</local>
<ejb-class>CalculatorBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
Session beans 2.1: Desventajas
 Necesidad de crear varios artefactos para definir el bean
(homes, interfaces, bean, descriptor)
 Alto acoplamiento con la API de EJB: modelo altamente
intrusivo. Necesidad de implementación de callbacks en el
bean
 Descriptores de deploy: complejidad en su mantenimiento.
Necesidad adicional de un descriptor propietario del EJB
container
Session beans 3.0
@Remote
public interface CalculatorRm
{
public int add(int a, int b);
}

@Local
public interface CalculatorLc
{
public int add(int a, int b);
}

@Stateless
public class CalculatorBean implements CalculatorRm, CalculatorLc
{
public int add(int a, int b) {return a + b;}
}
Session beans 3.0: Ventajas
 Modelo de desarrollo simplificado
 Las interfaces no necesitan extender interfaces EJB (son
POJIs)
 Los métodos de la interfaz remota no necesitan arrojar
RemoteException
 El bean no necesita implementar la interfaz callback
(SessionBean)
 El bean puede implementar varias interfaces de negocio
de una manera natural
 No existen componentes Home
 No se requiere el uso de descriptores (opcional)
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Business Interfaces (1)
 Un session bean puede implementar “n” interfaces de
negocio. La especificación preescribe que al menos una
debe implementar
 Pueden ser remotas o locales y se definen con
anotaciones
 Si sólo implementa una interfaz y la misma no está
anotada con la anotación @Remote o @Local se asume
que la misma es local
 Si el session no implementa interfaces el container puede
generar una automáticamente
Business Interfaces (2)
 Cuando las interfaces no están anotadas la accesibilidad
puede declararse en el mismo bean (de hecho el bean
puede no implementar las interfaces, aunque se
recomienda):

@Stateless
@Remote({CalculatorRm.class})
@Local({CalculatorLc.class})
public class CalculatorBean //implements CalculatorRm, CalculatorLc
{

}
Stateless Session beans
 Se define con la anotación @Stateless
 La anotación @Stateless puede opcionalmente definir un
atributo name que será el nombre JNDI con el que será
registrado el componente

@Stateless(name="Calculadora")
public class CalculatorBean implements CalculatorRm, CalculatorLc
{
public int add(int a, int b)
{
return a + b;
}
}
Stateful Session beans
 Se define con la anotación @Stateful
 La anotación @Stateful puede opcionalmente definir un
atributo name que será el nombre JNDI con el que será
registrado el componente
 Dado que no existen homes, se utilizan métodos de la
interfaz de negocio que adopten carácter de inicializadores
de la instancia
@Remote @Local
public interface ShoppingCartRm public interface ShoppingCartLc
{ {
public void addProduct(Product p); public void addProduct(Product p);
} }

@Stateful(name="ShoppingCart")
public class ShoppingCartBean
implements ShoppingCartRm, ShoppingCartLc
{ … }
Callbacks (1)
 EJB 3 evita al programador el tener que implementar
interfaces callbacks (SessionBean, por ej.)
 Cuando se necesita implementar lógica en alguno o todos
los puntos del ciclo de vida de los EJB, se utilizan
anotaciones para indicar los métodos del bean que
responderán ante los mismos
 Los métodos deben respetar una signature particular
 Esto resulta en un modelo mucho más flexible y menos
intrusivo
Callbacks (2)
 @PostConstruct: invocado luego de creada la instancia del
bean y resuelta la inyección de dependencias (Stateless,
Stateful)
 @PreDestroy: invocado previa a la eliminación de la
instancia del bean (Stateless, Stateful)
 @PrePasivate: invocado previo a la pasivación del bean
(Stateful)
 @PostActivate: invocado luego de la activación del bean
(Stateful)
 @Remove: invocado al momento de destruir la instancia
del bean. Finaliza con la vida de un session stateful
Callbacks (3)
@Stateless
public class CalculatorBean implements CalculatorRm, CalculatorLc
{

@PostConstruct
public void despuesDeConstruido() { … }

@PreDestroy
public void antesDeDestruir() { … }
}

@Stateful
public class ShoppingCartBean implements ShoppingCartRm, ShoppingCartLc
{

@PostActivate
public void luegoDeActivar() { … }

@Remove(retainIfException=true)
public void finalizarCompra() { … }
}

 El atributo retainIfException indica al container si el bean debe conservarse activo aun a pesar de que el
método arroje una excepción
Interceptores (1)
 EJB 3 introduce algunos conceptos de AOP de una manera
simplificada dentro del modelo de componentes
 Los interceptores son métodos que se ejecutan
transparentemente antes de la invocación a los métodos
de negocio del bean
 Se externalizan en clases separadas
 Se aplican a sessions stateless y stateful
Interceptores (2)
 Pueden definirse varios interceptores para un EJB y un
interceptor puede compartirse entre varios EJBs
 Cuando varios interceptores se definen para un EJB los
mismos forman una cadena de invocación de interceptores
 Existen 2 tipos:
 Delegados del ciclo de vida
 Interceptores AOP
Interceptores como delegados del
ciclo de vida
 Los métodos anotados dentro del bean como métodos del
ciclo de vida, también pueden definirse en una clase
externa
 La anotación @Interceptors define el arreglo de
interceptores que se registra para el bean
public class CalculatorCallbacks {
@PostConstruct
public void construct(InvocationContext ctx) { … }

@PreDestroy
public void destroy(InvocationContext ctx) { … }

//… otros métodos del ciclo de vida


}

@Stateless
@Interceptors({CalculatorCallbacks.class})
public class CalculatorBean implements CalculatorRm, CalculatorLc {

}
Interceptores AOP (1)
 El uso más interesante de los interceptores se da cuando
de aplica al uso de AOP sobre el bean. Ej clásico:
interceptor de logging
public class LoggerInterceptor {
@AroundInvoke
public Object logger(InvocationContext inv) throws Exception
{
System.out.println("Interceptando: " + inv.getMethod().getName());
Object[] params = inv.getParameters();
for (int i=0;i<params.length;i++)
{
System.out.println("\tparam: "+params[i]);
}
return inv.proceed();
}
}

@Stateless
@Interceptors({LoggerInterceptor.class})
public class CalculatorBean implements CalculatorRm, CalculatorLc {

}
Interceptores AOP (2)
 La anotación @AroundInvoke define al método como
método interceptor
 InvocationContext es pasado por parámetro por el
container para que el método acceda al contexto de la
llamada, tal como el bean target de la invocación, método
del bean llamado, sus parámetros, etc (recordar que un
interceptor puede reusarse en varios beans)
 Con InvocationContext el método puede decidir si
proceder la secuencia de ejecución (al próximo interceptor
o al bean) o abortarla
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Inyección de dependencias (1)
 El EJB 3 container provee un mecanismo de inyección de
dependencias, o más genéricamente, recursos (referencias
a otros EJBs, datasources, sessionContext, colas de
mensajería, userTransaction, etc)
 La inyección de dependencias implica la existencia de un
tercer agente diferente a las entidades “dependiente” y
“dependencia” el cual es instruido para hacer
corresponder la dependencia con el objeto dependiente
 Se utiliza la anotación @Resource
 El container soporta 2 mecanismos de inyección:
 Inyección por campo (variable)
 Inyección por setters
Inyección de dependencias (2)
 Inyecciones a nivel de campo:
@Resource
SessionContext context;
TaxRate tr = (TaxRate)context.lookup(TaxRate.class.getName());

@Resource(name="jdbc/__default", type=Datasource.class)
DataSource dataSource;

 Inyeccion por setter:


public class CalculatorBean implements CalculatorRm, CalculatorLc {
private myDataSource;
...
@Resource
private void setMyDataSource(DataSource ds) {
myDataSource = ds;
}
}
Inyección de dependencias (3)
 Existe también la posibilidad de inyectar varios recursos a
nivel de clase:
@Resources({
@Resource(name="datasource", type="javax.sql.DataSource.class"),
@Resource(name="queue", type="javax.jms.Queue")
})
public class CalculatorBean implements CalculatorRm, CalculatorLc
{
...
}
Inyección de dependencias (4)
 Cuando los recursos se inyectan a nivel de la clase no
quedan asociados a ninguna variable en particular, sino
que forman parte del entorno del bean
 El acceso a los mismos se realiza con un lookup JNDI por
el nombre del recurso declarado
 El lookup JNDI puede realizarse a través de un
InitialContext o bien con EJB 3 desde la interfaz
EJBContext (y derivadas)
 Esto permite al reutilización de dichos recursos desde
varias secciones del EJB
Inyección de dependencias (5)
 Existe una anotación particular para inyectar referencias
de un bean en otro: @EJB
 Esta anotación instruye al container la inicializacion de una
variable (por campo o por setter) con la referencia hacia
otro EJB a través de alguna de sus interfaces
public ShoppingCartBean implements ShoppingCarRm, ShoppingCartLc
{
//El container setea la referencia a este otro session
@EJB
private PricerLc pricer; //Bean que realiza cálculo de precios


}
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Transacciones (1)
 El modelo de transacciones de EJB 3 permanece igual al
impuesto por EJB 2.1, excepto por el hecho de no puede
asignarse transaccionabilidad directamente a un método
de un entity
 JTA API se utiliza para administrar programáticamente
transacciones
 Se utilizan anotaciones para definir a nivel del session
tanto el tipo de transacción a utilizar (BMT o CMT), como
los atributos de transaccionabilidad asociados a los
métodos cuando el modelo elegido es CMT
Transacciones (2)
 El tipo de transacción se define con la anotación
@TransactionManagement, la cual recibe los valores:
 TransactionManagementType.CONTAINER
 TransactionManagementType.BEAN
 Los atributos transaccionables de los métodos se definen
con la anotación @TransactionAttribute la cual recibe los
valores:
 TransactionAttributeType.MANDATORY
 TransactionAttributeType.NEVER
 TransactionAttributeType.NOT_SUPPORTED
 TransactionAttributeType.REQUIRED
 TransactionAttributeType.REQUIRES_NEW
 TransactionAttributeType.SUPPORTS
Transacciones (3)
 Ejemplo:

@Stateful
@TransactionManagement(TransactionManagementType.CONTAINER)
public class ShoppingCartBean implements ShoppingCartRm
{
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void addProduct(Product p) { … }
}

 Si un bean no declara (con anotaciones o en el descriptor)


que tipo de transacción solicita y sus atributos, se asume
que el tipo de transacción es CMT y Required para sus
métodos
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
EJB Entity Beans 2.1 (CMP)
public interface AddressLc extends EJBLocalObject
{
String getAddressID();
void setAddressID(String id);
String getStreet();
void setStreet(String street);
String getCity();
void setCity(String city);
}

public interface AddressLcHm extends EJBLocalHome


{
AddressLc create(String addressId) throws CreateException;
AddressLc findByPrimaryKey(String addressId) throws CreateException;
}
EJB Entity Beans 2.1 (CMP)
public abstract class AddressBean implements EntityBean {
private EntityContext context;

public abstract String getAddressID();


public abstract void setAddressID(String id);
public abstract String getStreet();
public abstract void setStreet(String street);
public abstract String getCity();
public abstract void setCity(String city);

public String ejbCreate (String id, String street, String city) throws
CreateException
{
setAddressID(id);
setStreet(street);
setCity(city);
setZip(zip);
setState(state);
return id;
}
...
}
EJB Entity Beans 2.1 (CMP)
<enterprise-beans>
<entity>
<ejb-name>AddressBean</ejb-name>
<local-home>AddressLcHm</local-home>
<local>AddressLc</local>
<ejb-class>AddressBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>false</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Address</abstract-schema-name>
<cmp-field>
<field-name>addressID</field-name>
</cmp-field>
<cmp-field>
<field-name>street</field-name>
</cmp-field>
<cmp-field>
<field-name>city</field-name>
</cmp-field>
<primkey-field>addressID</primkey-field>
</entity>
</enterprise-beans>
EJB Entity Beans 2.1 (CMP):
Desventajas
 Necesidad de crear varios artefactos para definir el bean
(homes, interfaces, bean, descriptor)
 Alto acoplamiento con la API de EJB: modelo altamente
intrusivo. Necesidad de implementación de callbacks en el
bean
 Descriptores de deploy: complejidad en su mantenimiento
 Complejidad en el manejo de relaciones entre entities
(CMP)
 Si el entity es BMP, la dificultad en el desarrollo y en el
mantenimiento es aún mayor
 Este modelo no soporta herencia ni polimorfismo
Entity bean 3.0
@Entity
@Table(name="ADDRESS")
public class AddressBean
{
private String addressId;
private String street;
private String city;

@Id
@Column(name="AddressId", primaryKey="true")
public String getAddressId() { return addressId; }

public void setAddressId(String pId) { this.addressId = pId;}

@Column(name="Street")
public String getStreet() { return street; }

public void setStreet(String street) { this.street = street; }

@Column(name="City")
public String getCity() { return city; }

public void setCity(String city) { this.city = city; }


}
Entity beans 3.0: Ventajas
 Modelo de desarrollo simplificado, menos intrusivo
 Desaparecen las interfaces, los objetos ahora son POJOs
 El bean no necesita implementar la interfaz callback
(EntityBean)
 No existen componentes Home
 No se requiere el uso de descriptores (opcional), tanto
para la definición del entity como para su mapeo y
relaciones con otros entities (se utilizan anotaciones)
 Soporta modelado OO: herencia y polimorfismo
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Entity beans
 Son los POJOs con los que se alimenta el mecanismo de
persistencia en EJB 3.0
 JPA provee servicios para la manipulación y administración
de entities
 Un entity es un objeto persistente que posee una
identidad asociada
Mapeo de entity beans 3.0 (1)
 Como se vio en el ejemplo anterior la forma de declarar a
un POJO como un Entity JPA es a través de la anotación
@Entity
 La clase debe tener al menos un constructor público o
protegido sin argumentos
 La clase no puede ser final
Mapeo de entity beans 3.0 (2)
 La anotación @Table se utiliza para indicar la tabla contra
la cual se mapea el bean
 El atributo name indica el nombre de la tabla
 La anotación es opcional, por ende, si se omite o bien no
se define el nombre de la tabla, se asume que el nombre
de la misma coincide con el del entity
@Entity
@Table(name="ADDRESS")
public class AddressBean
{

}
Mapeo de entity beans 3.0 (3)
 La anotación @Column se utiliza para mapear campos o
properties del bean con columnas de la tabla
 El atributo name indica el nombre de la columna
 La anotación es opcional, por ende, si se omite o bien no
se define el nombre de la columna, se asume que el
nombre de la misma coincide con el del campo o la
property del entity
 Para evitar la persistencia de un campo o property debe
utilizarse la anotación @Transient
Mapeo de entity beans 3.0 (4)
@Entity
@Table(name="ADDRESS")
public class AddressBean
{
@Column(name="Street") //Mapeo por property
public String getStreet()
{
return street;
}
}

@Entity
@Table(name="ADDRESS")
public class AddressBean
{
@Column(name="Street") //Mapeo por campo
protected String street;
}
Mapeo de entity beans 3.0 (5)
 Cuando el entity necesita persistirse en más de una tabla,
dichas tablas adicionales pueden indicarse con la
anotación @SecondaryTable
 De esta manera, algunos campos o propiedades pueden
persistirse en la tabla principal y otros en la tabla
secundaria
@Entity
@Table(name="CUSTOMER_TABLE")
@SecondaryTable(name="ADDRESS_TABLE",
pkJoinColumns={@PrimaryKeyJoinColumn(name="ADDRESS_ID")})
public class Customer {
private long id;
private String street;
private String city;
... //campos de Customer

@Column(name="STREET", table="ADDRESS_TABLE")
public String getStreet( ) { return street; }

@Column(name="CITY", table="ADDRESS_TABLE")
public String getCity( ) { return city; }
}
Mapeo de entity beans 3.0 (6)
 En el caso del ejemplo anterior la dirección se relaciona
con su cliente a través de una FK la cual es a su vez PK de
la tabla de direcciones
 La anotación @PrimaryKeyJoinColumn especifica la
columna en la tabla de direcciones que hará join con la PK
de la tabla de clientes. El JPA provider deduce cuál es la
PK de la tabla de clientes
 Si un entity necesita más de una tabla secundaria se
utiliza la anotación @SecondaryTables
@Entity
@Table(name="CUSTOMER_TABLE")
@SecondaryTables({
@SecondaryTable(name="ADDRESS_TABLE",
pkJoinColumns={@PrimaryKeyJoinColumn (name="ADDRESS_ID")}),
@SecondaryTable(name="CREDIT_CARD_TABLE",
pkJoinColumns={@PrimaryKeyJoinColumn (name="CC_ID")})})
public class Customer{ … }
Claves primarias (1)
 En EJB 3 existen 3 formas para indicar al JPA provider cuál
es la clave primaria del POJO, en grado ascendente de
complejidad:
 @Id

 @IdClass

 @EmbeddedId
Claves primarias (2)
 La anotación @Id marca un campo o una property como
la clave primaria del mismo
 Acepta tipos primitivos, wrappers de primitivos y tipos
serializables como String, java.util.Date y java.sql.Date
 Sólo funciona con claves simples de un campo, no
funciona con claves compuestas
@Entity
public class Product
{
private Long id = null;

@Id
public Long getId()
{
return id;
}
}
Claves primarias (3)
 La anotación @IdClass se utiliza para claves compuestas
 Externaliza el comportamiento de comparación de claves
del que hace uso el JPA provider
 La clase de la pk debe ser Serializable y debe tener una
implementación válida de hashCode()
 El POJO conserva los campos de su pk y no necesita
conocer de la existencia de la misma
Claves primarias (4)
public class AutoPKey implements Serializable
{
String marca, modelo;

public AutoPKey() { }

public boolean equals(Object o) { … }

public int hashCode() { … }


}

@Entity
@IdClass(AutoPKey .class)
public class Auto
{
@Id
protected String marca;
@Id
protected String modelo;

public Auto() { }
...
}
Claves primarias (5)
 La anotación EmbeddedId se utiliza para claves
compuestas
 Similar a @IdClass excepto que el POJO sí debe conocer la
pk ya que la misma está embebida en el objeto
 La pk no necesita ser Serializable
Claves primarias (6)
@Embeddable
public class AutoPKey
{
String marca, modelo;

public AutoPKey() { }

public boolean equals(Object o) { … }

public int hashCode() { … }


}

@Entity
public class Auto
{
@EmbeddedId
protected AutoPKey autoPKey;

public Auto() { }
...
}
Entities embebibles (1)
 Son objetos dependientes de entities JPA
 No tienen identidad propia (PK), sino que comparten la
identidad del owner
 “Viven” dentro de una entidad
 Normalmente se persisten en la misma tabla (y mismo
registro) que el entity padre
 En caso de necesitar persistir el objeto embebible en otra
tabla, utilizar @SecondaryTable
Entities embebibles (2)
@Entity
@Table(name="USERS")
public class User implements Serializable
{
@Id
@Column(name="USER_ID", nullable=false)
protected Long userId;
...
@Embedded
protected Address address;
...
}

@Embeddable
public class Address implements Serializable
{
//Los nombres de columna hacen referencia a columnas
//de la tabla del owner ("USERS")
@Column(name="STREET", nullable=false)
protected String street;
...
@Column(name="ZIP_CODE", nullable=false)
protected String zipCode;
...
}
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Relaciones entre entities
 JPA soporta 4 tipos de relaciones entre entities expresadas
a través de anotaciones
 Uno a uno

 Uno a muchos

 Muchos a uno

 Muchos a muchos

 Las relaciones pueden ser unidireccionales o


bidireccionales (7 tipos en total siendo que la relación
bidireccional uno a muchos es equivalente a la relación
bidireccional muchos a uno)
Relación uno a uno unidireccional
(1)
 Se utiliza la anotación @OneToOne en el entity owner de
la relación
@Entity
public class Customer implements Serializable
{
...
@OneToOne
@JoinColumn(name="MAILING_ADDRESS_REF",
referencedColumnName="ADDRESS_PK")
protected Address address;
...
}

@Entity
public class Address
{
...
}
Relación uno a uno unidireccional
(2)
 La anotación @JoinColumn establece el enlace entre las
tablas (en el esquema típicamente será una relación de FK
a PK)
 @OneToOne recibe un atributo boolean optional en el cual
se indica si la relación debe ser no nula (optional=false) o
si acepta null (optional=true). El default es true
 La anotación @OneToOne así como todas las anotaciones
que establecen relaciones pueden recibir un atributo
cascade que indica al motor qué operaciones realizadas
sobre un entity deben también aplicarse hacia su o sus
entities relacionados
Relación uno a uno unidireccional
(3)
 El atributo cascade puede recibir un array de los
siguientes valores de la enumeración CascadeType:
PERSIST, MERGE, REMOVE, REFRESH y ALL.
 CascadeType.ALL es equivalente a enumerar todos los
tipos
@Entity
public class Customer implements Serializable
{
...
@OneToOne(cascade={CascadeType.PERSIST})
@JoinColumn(name="MAILING_ADDRESS_REF",
referencedColumnName="ADDRESS_PK")
protected Address address;
...
} //Esto implica que ante una operación de
//persistencia de Customer también se persiste la Dirección
Relación uno a uno bidireccional
 Implica utilizar además la anotación @OneToOne en el
otro extremo de la relación indicando la property del entity
origen que referencia a este extremo de la relación

@Entity
public class Address implements Serializable
{
...
//"address" es el nombre de la property en
//Customer que referencia a este entity
@OneToOne(mappedBy="address")
protected Customer customer;
...
}
Relación uno a muchos
unidireccional (1)
 Se utiliza la anotación @OneToMany en el entity owner de
la relación:
@Entity
public class Company implements Serializable
{
...
private Collection<Employee> employees;
...
@OneToMany(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
public Collection<Employee> getEmployees()
{
return employees;
}

public void setEmployees(Collection<Employee> employees)


{
this.employees = employees;
}
}
Relación uno a muchos
unidireccional (2)
 Como se puede apreciar, el empleado no conoce a su
compañía:

@Entity
public class Employee
{
private int id;
private String name;
private char sex;
...
}
Relación uno a muchos
bidireccional (1)
 Implica utilizar la anotación @OneToMany en el entity
origen de la relación indicando el nombre de la property
en el entity destino que participa de la relación
@Entity
public class Company implements Serializable
{
...
private Collection<Employee> employees;
...
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER,
mappedBy=”company”)
public Collection<Employee> getEmployees()
{
return employees;
}

public void setEmployees(Collection<Employee> employees)


{
this.employees = employees;
}
}
Relación uno a muchos
bidireccional (2)
 Además en el entity destino debe usarse la anotación
@ManyToOne para referenciar a su origen
 @ ManyToOne recibe un atributo boolean optional en el
cual se indica si la relación debe ser no nula
(optional=false) o si acepta null (optional=true). El default
es true
 En este tipo de relación bidireccional, en verdad el owner
de la relación es el entity que posee la anotación
@ManyToOne. Es por eso que dicha anotación no posee
en atributo mappedBy y si en cambio lo posee la
anotación @OneToMany
Relación uno a muchos
bidireccional (3)
@Entity
public class Employee implements Serializable
{
...
private Company company;
...
@ManyToOne
public Company getCompany()
{
return company;
}

public void setCompany(Company company)


{
this.company = company;
}
}
Relación muchos a muchos (1)
 Muchos a muchos unidireccional no es muy común, por eso sólo trataremos
la variante bidireccional
 Se utiliza la anotación @ManyToMany
 Examinemos una relación muchos a muchos entre Categoría e Items. Una
categoría puede tener muchos items, y un item puede estar en varias
categorías
Relación muchos a muchos (2)
 El mapeo para el entity owner sería el siguiente:
@Entity
@Table(name="CATEGORIES")
public class Category implements Serializable
{
@Id
@Column(name="CATEGORY_ID")
protected Long categoryId;

@ManyToMany
@JoinTable(name="CATEGORY_ITEMS",
joinColumns=
@JoinColumn(name="CI_CATEGORY_ID",
referencedColumnName="CATEGORY_ID"),
inverseJoinColumns=
@JoinColumn(name="CI_ITEM_ID",
referencedColumnName="ITEM_ID"))
protected Set<Item> items;
...
}
Relación muchos a muchos (3)
 El mapeo para el entity subordinado sería el siguiente:
@Entity
@Table(name="ITEMS")
public class Item implements Serializable
{
@Id
@Column(name="ITEM_ID")
protected Long itemId;
...
@ManyToMany(mappedBy="items")
protected Set<Category> categories;
...
}
Relación muchos a muchos (4)
 La anotación @JoinTable describe el mapeo entre las
tablas a través de la tabla asociativa
 Los atributos joinColumns e inverseJoinColumns describen
la condición de join a ambos lados de la relación
 joinColumn identifica al owner de la relación (Category)
 inverseJoinColumns identifica al subordinado de la relación
(Item)
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Herencia de entities (1)
 JPA soporta 2 mecanismos para el mapeo de herencia de
entities en tablas:
 Single table per class hierarchy

 Joined subclass strategy

 Existe un tercer mecanismo que puede opcionalmente


estar soportado por el JPA Provider pero no es requerido
por la especificación
Herencia de entities (2)
 Imaginemos el siguiente diagrama de clases:
Herencia de entities (3)
 Entity RoadVehicle:
@Entity
public class RoadVehicle
{
public enum AcceleratorType {PEDAL,THROTTLE};
protected int numPassengers;
protected int numWheels;
protected String make;
protected String model;

// setters and getters go here


...
public String toString()
{
return "Make: "+make+ " Model: " +model+
" Number of passengers: "+numPassengers;
}
}
Herencia de entities (4)
 Entity motorcycle:
@Entity
public class Motorcycle extends RoadVehicle
{
public final AcceleratorType acceleratorType =
AcceleratorType.THROTTLE;
public Motorcycle()
{
numWheels = 2;
numPassengers = 2;
}

public String toString()


{
return "Motorcycle: "+super.toString();
}
}
Herencia de entities (5)
 Entity Car:
@Entity
public class Car extends RoadVehicle
{
public final AcceleratorType acceleratorType =
AcceleratorType.PEDAL;
public Car()
{
numWheels = 4;
}

public String toString()


{
return "Car: "+super.toString();
}
}
Herencia de entities (6)
 Entity Roadster:
@Entity
public class Roadster extends Car
{
public enum CoolFactor{COOL,COOLER,COOLEST};
private CoolFactor coolFactor;

public Roadster()
{
numPassengers = 2;
}
// setters and getters go here
...

public String toString()


{
return "Roadster: "+super.toString();
}
}
Herencia de entities (7)
 Entity Coupe:
@Entity
public class Coupe extends Car
{
public enum BoringFactor {BORING,BORINGER,BORINGEST};
private BoringFactor boringFactor;

public Coupe()
{
numPassengers = 5;
}
// setters and getters go here
...

public String toString()


{
return "Coupe: "+super.toString();
}
}
Single Table per Class Hierarchy
(1)
 Se utiliza una sola tabla para persistir toda la jerarquía de
objetos
 Se identifica con la anotación @Inheritance y su atributo
strategy seteado con el valor
InheritanceType.SINGLE_TABLE
 La anotación @DiscriminatorColumn se utiliza para
identificar la columna (y su tipo) que poseerá los valores
que identificarán a cada elemento de la jerarquía
 La anotación @DiscriminatorValue identifica para cada
entity cuál será el valor que tomará el discriminador para
identificar a esa instancia
Single Table per Class Hierarchy
(2)
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="DISC", discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue("ROADVEHICLE")
public class RoadVehicle implements Serializable
{
...
}

@Entity
@DiscriminatorValue("MOTORCYCLE")
public class Motorcycle extends RoadVehicle implements Serializable
{
...
}

@Entity
@DiscriminatorValue("CAR")
public class Car extends RoadVehicle implements Serializable
{
...
}
Single Table per Class Hierarchy
(3)
@Entity
@DiscriminatorValue("ROADSTER")
public class Roadster extends Car implements Serializable
{
...
}

@Entity
@DiscriminatorValue("COUPE")
public class Coupe extends Car implements Serializable
{
...
}
Single Table per Class Hierarchy:
Ventajas y desventajas
 Ventajas:
 Es eficiente en la persistencia y obtención de los

entities, debido a que se utiliza una sola tabla


 Desventajas:
 La tabla puede volverse muy ancha ya que se necesita

una columna por cada atributo de cada elemento de la


jerarquía. Esto se agrava cuanto más profunda es la
jerarquía
 Cada columna que se mapea a una property de una

subclase debe ser nullable


Joined subclass strategy
 Se utiliza una tabla “maestra” que representa sólo los
atributos del root de la jerarquía
 Luego existe una tabla aparte por cada subclase que
posee columnas únicamente para sus atributos
 Se identifica con la anotación @Inheritance y su atributo
strategy seteado con el valor InheritanceType.JOINED
 La anotación @DiscriminatorColumn se utiliza para
identificar la columna (y su tipo) que poseerá los valores
que identificarán a cada elemento de la jerarquía en la
tabla maestra
 La anotación @DiscriminatorValue identifica para cada
entity cuál será el valor que tomará el discriminador para
identificar a esa instancia en la tabla maestra
Joined subclass strategy
 La definición de las clases permanece igual que el ejemplo
anterior, variando únicamente la definición de la
superclase:

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="DISC", discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue("ROADVEHICLE")
public class RoadVehicle
{
...
}
Joined subclass strategy: Ventajas
y desventajas
 Ventajas:
 Es mejor que la estrategia anterior desde el punto de

vista de diseño
 Encapsula los atributos propios de cada clase en tablas

separadas
 Desventajas:
 Performance: debido a que para materializar una

subclase se necesitan hacer varios joins dependiendo


de la profundidad de la jerarquía, cuanto más profunda
es la misma más costosa es la obtención de una
entidad
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
JPA
 Es la API standard para el manejo de persistencia de
objetos dentro de la plataforma Java
 Especificación de un ORM basado en ORMs conocidos en
la industria: Hibernate, TopLink, JDO, etc.
 Es parte de Java EE 5, pero mantendrá una línea de
evolución independiente en el futuro
JPA: Características principales
 Modelo de desarrollo simplificado basado en POJOs
 Usabilidad fuera del container en aplicaciones J2SE
 Facilidad de testeo
 Modelo no intrusivo, permite modelado OO
 Basado en un modelo de proveedor del servicio de
persistencia, esto permite independencia y desacople con
la implementación real del motor
 Independencia con el motor de BD
EntityManager (1)
 Es la fachada de servicios de JPA
 Sus servicios operan sobre entities
 Todo cliente que quiera interactuar con entidades
persistentes debe primero obtener una instancia del
EntityManager
 Provee operaciones de búsqueda, update, refresh, remove
y persistencia de nuevas entidades
EntityManager (2)
 La especificación de persistencia JPA define un SPI
(Service Provider Interface) el cual define un mecanismo
de proveedor de persistencia pluggable
 El EntityManager es la interfaz utilizada para interactuar
con un persistence context
 Es el artefacto más importante en JPA y el responsable de
mayor peso en los servicios de ORM que provee la API
Persistence Context
 Define el contexto en el cual viven y se administran los
entities manipulados a través de una instancia del
EntityManager
 Definición oficial en la especificación: “es un conjunto de
instancias de entities en donde para cada identidad
persistente existe una única instancia de entity asociada”
(define la univocidad de entities)
 Todo el ciclo de vida de los entities se produce dentro de
un contexto de persistencia dado, al cual se accede a
través de los servicios del EntityManager
Persistence Unit
 Define el conjunto de entities y su configuración de mapeo
(opcional), que se asocia a un mismo recurso de datos
(base de datos)
 Un EntityManager tiene una relación uno a uno con un
persistence context y a su vez éste tiene una relación uno
a uno con una unidad de persistencia
 Una aplicación puede definir varias unidades de
persistencia, pero al menos debe definir una
Persistence.xml (1)
 Las unidades de persistencia se definen en un archivo
denominado persistence.xml
 Debe definir al menos una unidad de persistencia
 Se coloca en el directorio META-INF de un archivo .jar,
ejb-jar, .ear o .war
 Sin este archivo no existen las unidades de persistencia y
sin unidades de persistencia no pueden obtenerse
instancias de EntityManager
 En este xml se declara para cada unidad de persistencia el
nombre, una descripción, el provider asociado, las
properties de configuración del mismo, el tipo de
transacción (JTA o Local), etc
Persistence.xml (2)
<persistence-unit name="OrderManagement">
<description>
Administra inventario para auto partes.
</description>
<provider>com.acme.AcmePersistence</provider>
<jta-data-source>jdbc/MyPartDB</jta-data-source>
<mapping-file>ormap2.xml</mapping-file>
<jar-file>MyPartsApp.jar</jar-file>
<properties>
<property name="com.acme.persistence.sql-logging“ value="on"/>
</properties>
</persistence-unit>
<persistence-unit name=“CustomerAdmin">
<class>ejemplo.Customer</class>
<properties>
<property name="jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbc.url“ value="jdbc:oracle:thin:@localhost:1521:ORCL"/>
<property name="jdbc.user" value="jwetherb"/>
<property name="jdbc.password" value="jwetherb"/>
<property name="platform.class.name“
value="oracle.toplink.essentials.platform.database.oracle.OraclePlatform"/>
</properties>
</persistence-unit>
Obtención de un EntityManager
 Existen diferentes formas de obtener una instancia
dependiendo del tipo de aplicación
 En entornos JEE el EntityManager es administrado por el
container y se obtiene de 2 formas posibles:
 Inyección

 Lookup JNDI

 En entornos JSE el EntityManager es administrado por la


aplicación y se obtiene a través del EntityManagerFactory
EntityManager en entornos JEE:
por inyección
 Se utiliza la anotación @PersistenceContext
@Remote(Bank.class)
public class BankBean implements Bank {
@PersistenceContext
private EntityManager manager;

public Account openAccount(String ownerName) {


Account account = new Account();
account.ownerName = ownerName;
manager.persist(account);
return account;
}
public int getBalance(int accountNumber) {
Account account = manager.find(Account.class, accountNumber);
return account.balance;
}
public void deposit(int accountNumber, int amount) {
Account account = manager.find(Account.class, accountNumber);
account.deposit(amount);
}
public int withdraw(int accountNumber, int amount) {
Account account = manager.find(Account.class, accountNumber);
return account.withdraw(amount);
}
public void close(int accountNumber) {
Account account = manager.find(Account.class, accountNumber);
manager.remove(account);
}
}
EntityManager en entornos JEE:
por JNDI
 Para la búsqueda por JNDI podemos por ej. inyectar el
context y luego buscarlo a través del mismo
 Otra alternativa similar sería utilizando simplemente un
InitialContext
@Stateless
//esta anotación define el recurso (ctx de persistencia) en el entorno del bean,
//para luego poder ser accedido por JNDI
@PersistenceContext(name="BankEM")
public class BankBean implements Bank {
@Resource SessionContext ctx;

public Account openAccount(String ownerName) {


EntityManager em = (EntityManager)ctx.lookup(“BankEM");
Account account = new Account();
account.ownerName = ownerName;
manager.persist(account);
return account;
}
}
EntityManager en entornos JSE:
por factory (1)
 Si bien se utiliza mayormente para aplicaciones JSE
también puede utilizarse en entornos JEE
 Se utiliza la interfaz EntityManagerFactory
 El factory queda asociado a una unidad de persistencia
específica, de esta manera devuelve instancias de
EntityManager que acceden al mismo recurso de datos
 El ciclo de vida de los EntityManager queda a
responsabilidad de la aplicación
EntityManager en entornos JSE:
por factory (2)
 Para entornos JSE se utiliza la clase bootstrap
javax.persistence.Persistence la cual provee acceso al
factory, pasándole como parámetro el nombre de una
unidad de persistencia:
EntityManagerFactory emf =
javax.persistence.Persistence.createEntityManagerFactory("Order");
EntityManager em = emf.createEntityManager();

 Para entornos JEE el factory se obtiene por lookup JNDI o


bien con el uso de la anotación @PersistenceUnit. Esta
anotación puede opcionalmente recibir un atributo
unitName con el nombre de la unidad de persistencia
sobre la que operarán los EntityManager devueltos por
dicho factory
@PersistenceUnit
EntityManagerFactory emf;
Tiempo de vida del contexto de
persistencia
 El contexto de persistencia asociado a un EntityManager
administrado (por el container) puede ser de 1 de 2 tipos
posibles
 Transaction-scoped

 Extended-scoped

 Definen el scope del contexto de persistencia asociado al


EntityManager
Transaction-scoped persistence
context (1)
 Está asociado al contexto de la transacción activa
 Su tiempo de vida transcurre desde el momento que la
transacción se inicia hacia que finaliza (con commit o
rollback)
 Al estar asociados a un contexto transaccional JTA el
container propaga el contexto de persistencia en todo el
flujo de la transacción de manera que todas las
referencias de EntityManager utilizadas que estén
asociadas a la misma unidad de persistencia compartan el
mismo contexto de persistencia
Transaction-scoped persistence
context (2)
 Se define con la enumeración
PersistenceContextType.TRANSACTION
 Por defecto un EntityManager queda asociado a un
contexto dentro de este scope
 Utilizado típicamente en session beans stateless
Extended-scoped persistence
context (1)
 No está asociado a ninguna transacción en particular y
puede abarcar muchas transacciones
 Se define con la enumeración
PersistenceContextType.EXTENDED
 Utilizado típicamente en session beans stateful
 Su tiempo de vida transcurre desde el momento que se
crea hasta que el bean es removido por el container
Extended-scoped persistence
context (2)
@Stateful
@Remote(AccountInterface.class)
public class AccountBean implements AccountInterface {
@PersistenceContext(type=PersistenceContextType.EXTENDED, unitName=”intro”)
private EntityManager manager;

private Account account = null;

public int getBalance() {


if(account==null)
throw new IllegalStateException();
return account.balance;
}

public void deposit(int amount) {


if(account==null)
throw new IllegalStateException();
account.deposit(amount);
}

public int withdraw(int amount) {


if(account==null)
throw new IllegalStateException();
return account.withdraw(amount);
}
}
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Ciclo de vida de los entities (1)
 La vida de un entity tiene 2 aspectos fundamentales: la
relación con su contexto de persistencia y la sincronización
de su estado con la BD
Ciclo de vida de los entities (2)
 New: el entity existe en memoria pero no tiene asociada
una identidad persistente en la BD o un contexto de
persistencia
 Managed: el entity tiene asociado una identidad y un
contexto de persistencia y el EntityManager mantiene
sincronizado su estado al momento de commit de la tx o
bien al llamar al método flush()
Ciclo de vida de los entities (3)
 Detached: el entity no es administrado por el
EntityManager, no está asociado a ningún contexto de
persistencia. Un entity administrado (managed) se
“detachea” al momento en que finaliza la vida del contexto
de persistencia (scope, sesión) o cuando se serializa (por
ej. al ser enviado entre capas)
 Removed: el entity puede estar asociado al contexto de
persistencia pero está marcado para eliminación al
momento de finalizar la tx
Ciclo de vida de los entities:
callbacks (1)
 Similar al mecanismo provisto para Session beans
 El JPA Provider provee hooks mediante anotaciones para
designar métodos que se invocarán cuando el entity
efectue la transición hacia otro estado
 Utilizado por ej para logging, validación de datos,
auditoría, etc
Ciclo de vida de los entities:
callbacks (2)
 Las anotaciones definidas para el ciclo de vida son:
 @PrePersist: antes de que el EntityManager persista

una instancia del entity


 @PostPersist: luego de que un entity ha sido persistido

 @PostLoad: luego de que un entity haya sido cargado

por una operación de query, find o refresh


 @PreUpdate: antes de que un update de la BD suceda

para sincronizar la instancia del entity


 @PostUpdate: luego de que un update de la BD haya

sucedido para sincronizar la instancia del entity


 @PreRemove: antes de que el EntityManager remueva

el entity
 @PostRemove: luego de que un entity haya sido

removido
Ciclo de vida de los entities:
callbacks (3)
 Las anotaciones pueden utilizarse directamente sobre
métodos del entity o bien sobre una clase listener
separada
public class ItemMonitor {
...
public ItemMonitor() {}

@PrePersist
@PreUpdate
public void monitorItem(Item item) {
System.out.println("Monitoreando entity antes de sincronizar...")
}
}

@Entity
@EntityListeners(ItemMonitor.class)
public class Item implements Serializable {
...
}
Agenda
 Introducción
 Session beans
 Session beans 2.1 vs. Session beans 3.0
 Analizando session beans 3.0
 Inyección de dependencias
 Transacciones
 Entity beans
 Entity beans 2.1 vs. Entity beans 3.0
 Analizando entity beans 3.0
 Relaciones
 Herencia
 JPA: Java Persistence API
 Analizando JPA
 Ciclo de vida de los entities
 Query API y JPQL
Query API
 Está formada por los métodos del EntityManager para
crear queries, los métodos en la interfaz Query para
ejecutarlos y el lenguaje de consulta: JPQL
JPQL: Java Persistence Query
Languaje
 Lenguaje de consulta, delete y update que opera sobre
entities
 Similar a SQL pero no está orientado al mundo relacional
(tablas y columnas) sino al mundo de objetos (entities y
atributos)
 Es básicamente una extensión de EJB QL 2.1 con algunas
características adicionales
 Permite independizarse de la base de datos y del esquema
relacional
 Permite la utilización de queries nativos en SQL
JPQL: Queries
 EntityManager provee el método find para localizar
entities, de la forma:

public <T> T find(Class<T> entityClass, Object primaryKey);

 Pero cuando se requiere flexibilidad de búsqueda de


entities, más allá de sus PKs es necesario definir queries
 Existen 2 tipos de queries
 Dinámicos
 Estáticos
Queries dinámicos
 Se definen al momento de utilizarlos
 No están pensados para ser reusados
 Los construye “on the fly” el EntityManager
 Se los puede definir usando JPQL o SQL nativo (en este
caso llamando al método createNativeQuery(…))
 Ejemplo: imaginemos un método de un session bean que
devuelve el conjunto de entities de empleados utilizando
JPQL:
@PersistentContext em;
...
public List findAllEmployees() {
Query query = em.createQuery("SELECT e FROM Employee e");
return query.getResultList();
}
Queries estáticos
 Se definen para ser reusados
 Declarados en 2 posibles lugares: sobre el entity o en un
archivo XML
 Favorecen la mantenibilidad del código
 Pueden aumentar la performance ya que se preparan una
sola vez y luego se reusan cada vez que son llamados
 Se utiliza la anotación @NamedQuery y/o @NamedQueries
Queries estáticos: Ejemplo
 Se definen de la siguiente forma:
@Entity
@NamedQueries({
@NamedQuery(
name = "findAllEmployees",
query = "SELECT e FROM Employee e"
),
@NamedQuery(
name = "findAllEmployeesSorted",
query = " SELECT e FROM Employee e ORDER BY e.name"
)
})
@Table(name = "EMPLOYEES")
public class Empleado implements Serializable
{
...
}
Queries estáticos: Ejemplo
 Se utilizan de la siguiente forma, pasando por parámetro
el nombre con el que se definió el query:

@PersistentContext em;
...
public List findAllEmployees()
{
Query query = em.createNamedQuery("findAllEmployees");
return query.getResultList();
}
Parametrización de queries
 Un query puede parametrizarse mediante 2 tipos de
parámetros:
 Posicionales

 Por nombre

 Implican el uso de una cláusula WHERE


 Además la interfaz Query provee métodos para paginar
consultas que devuelven colecciones de entities
Parámetros posicionales
 Como su nombre lo indica se los identifica por el orden de
aparición dentro de la cadena del query
 Ejemplo: obtener todos los entities de empleados que
tienen entre 25 y 40 años

@PersistentContext em;
...
public List findAllEmployees() {
Query query = em.createQuery(
"SELECT e FROM Employee e WHERE e.age > ?1 AND e.age < ?2");
query.setParameter(1, 25);
query.setParameter(2, 40);
return query.getResultList();
}
Parámetros por nombre
 Se los identifica con un nombre o una etiqueta dentro de
la cadena del query
 Mismo ejemplo: obtener todos los entities de empleados
que tienen entre 25 y 40 años

@PersistentContext em;
...
public List findAllEmployees() {
Query query = em.createQuery(
"SELECT e FROM Employee e WHERE e.age > :lowerLimit AND e.age
< :upperLimit");
query.setParameter("lowerLimit", 25);
query.setParameter("upperLimit", 40);
return query.getResultList();
}
Capacidades de Query API
 Esto solo raya la superficie de esta API
 JPQL agrega a EJB QL 2.1, además de
los visto:
 Queries polimórficos
 Updates y deletes batch (bulk)
 Subqueries
 Uso de JOIN, GROUP BY, HAVING
 Etc.
EJB 3.0

?
Referencias
 Libros:
 Mastering Enterprise JavaBeans 3.0. Ed: Wiley
 EJB 3 In Action. Ed: Manning
 Beginning EJB 3 Application Development. Ed: Appres
 Especificación en:
 http://java.sun.com/products/ejb/docs.html

También podría gustarte