Anda di halaman 1dari 19

Caso de estudio: diseo e implementacin de la capa modelo de MiniBank con EJB

Introduccin
La arquitectura de la capa modelo de MiniBank es igual que la de MiniPortal Paquetes nuevos en la capa modelo
Clases Entidad Account y AccountOperation
es.udc.fbellas.j2ee.minibank.model.account.entity es.udc.fbellas.j2ee.minibank.model.accountoperation.entity

Implementacin de los casos de uso (AccountFacade)


es.udc.fbellas.j2ee.minibank.model.accountfacade.ejb y es.udc.fbellas.j2ee.minibank.model.accountfacade.ejb.actions

Qu aspectos nuevos aporta el estudio de la capa modelo de MiniBank con respecto a la de MiniPortal?
El soporte del API de Persistencia para la generacin numrica de identificadores El soporte del API de Persistencia para la implementacin del patrn Page-by-Page Iterator Implementacin de Stateless Session Beans

Generacin numrica de identificadores


En las clases entidad Account y AccountOperation se han usado anotaciones especiales en la propiedad de la clave primaria para que
Los valores se generen mediante una secuencia (si la base de datos proporciona secuencias) Se mapee a una columna contador (si la base de datos ofrece columnas contador)

Al igual que en MiniPortal, no se han generado nuevas tablas, sino que se utilizan las mismas que las de la versin JDBC de la capa modelo de MiniBank (inclusive las secuencias)

Ejemplo: AccountOperation (1)


@Entity @Table(name="AccountOp") public class AccountOperation { private private private private private Long accountOperationIdentifier; Long accountIdentifier; Calendar date; byte type; double amount;

public AccountOperation() {} public AccountOperation(Long accountIdentifier, Calendar date, byte type, double amount) { this.accountIdentifier = accountIdentifier; this.date = date; this.type = type; this.amount = amount; }

Ejemplo: AccountOperation (2)


@Column(name="accOpId") @SequenceGenerator( // It only takes effect name="AccountOperationIdentifierGenerator", // for databases provi// ding intentifier sequenceName="AccountOpSeq") // generators. @Id @GeneratedValue(strategy=GenerationType.AUTO, generator="AccountOperationIdentifierGenerator") public Long getAccountOperationIdentifier() { return accountOperationIdentifier; } public void setAccountOperationIdentifier( Long accountOperationIdentifier) { this.accountOperationIdentifier = accountOperationIdentifier; } @Column(name="accId") public Long getAccountIdentifier() { return accountIdentifier; } public void setAccountIdentifier(Long accountIdentifier) { this.accountIdentifier = accountIdentifier; }

Ejemplo: AccountOperation (y 3)
@Temporal(TemporalType.TIMESTAMP) public Calendar getDate() { return date; } public void setDate(Calendar date) { this.date = date; } public byte getType() { return type; } public void setType(byte type) { this.type = type; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } }

Anotaciones para generacin de identificadores numricos (1)

@GeneratedValue
stategy
Especifica la estrategia de generacin de identificadores numricos Es de tipo GenerationType (enumerado) SEQUENCE: usar una secuencia IDENTITY: mapear la clave a una columna contador TABLE: usar una tabla para emular un conjunto de secuencias (cada fila es una secuencia para una entidad particular) AUTO: la implementacin del API de Persistencia decide la estrategia en funcin de la BD que se est usando

generator
Especifica el nombre del generador que se usar en el caso de las estrategias TABLE o SEQUENCE

Anotaciones para generacin de identificadores numricos (2)

@SequenceGenerator
Especifica informacin de mapeo para un generador que se puede usar con la estrategia SEQUENCE name: nombre del generador sequenceName: nombre de la secuencia

@TableGenerator
Especifica informacin de mapeo para un generador que se puede usar con la estrategia TABLE La estrategia SEQUENCE es ms eficiente

Los atributos/propiedades anotadas tienen que ser de tipo entero (short, int, long y sus contrapartidas objetuales)

Anotaciones para generacin de identificadores numricos (y 3) Cmo se puede especificar que la implementacin del API de Persistencia utilice secuencias o columnas contador para la propiedad accountOperationIdentifier?
En el ejemplo se ha especificado
@GeneratedValue(strategy=GenerationType.AUTO, generator="AccountOperationIdentifierGenerator")

JBoss utiliza la estrategia IDENTITY para MySQL y SEQUENCE para PostgreSQL (utiliza la informacin del generador especificado) Si la implementacin del API de Persistencia no es tan inteligente, habra que especificar (dependiendo del tipo de BD)
@GeneratedValue(strategy=GenerationType.IDENTITY)

... o ...
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="AccountOperationIdentifierGenerator")

Otros aspectos (1)


El constructor con argumentos deja el atributo accountOperationIdentifier sin inicializar
La implementacin de los casos de uso invoca este constructor cuando tiene que crear una instancia de AccountOperation No puede dar valor al atributo accountOperationIdentifier: es la implementacin del API de Persistencia la que le asignar valor tras la invocacin de EntityManager.persist (invocando el mtodo setAccountOperationIdentifier)
AccountOperation accountOperation = new AccountOperation(...); // "accountOperationIdentifier" todava no tiene valor asignado. entityManager.persist(accountOperation); // "accountOperationIdentifier" ya tiene valor asignado.

Se ha usado la anotacin @Table para especificar que la entidad AccountOperation se mapea a la tabla AccountOp

Otros aspectos (y 2)
@Temporal
Para los atributos/propiedades de tipo Calendar hay que especificar el mapping que se desea
TemporalType.DATE, TemporalType.TIME o TemporalType.TIMESTAMP

No se ha incluido una propiedad anotada con @Version, dado que las instancias de AccountOperation no son modificables (y en consecuencia, no es til)

Page-by-Page Iterator (1)


En MiniBank se hace uso del lenguaje de consultas EJB-QL para la implementacin de los caso de uso
Encontrar las cuentas de un usuario Encontrar las operaciones bancarias realizadas sobre una cuenta entre dos fechas

El lenguaje EJB-QL se estudia en el apartado 5.5 El API de Persistencia permite lanzar una consulta de bsqueda y obtener
Todos los resultados, o Un rango de resultados (Page-by-Page Iterator)

Page-by-Page Iterator (2)


Ejemplo: en la implementacin del caso de uso findAccountOperationsByDate (cont)
/* * Find count+1 account operations to determine if there exist more * account operations above the specified range. */ List<AccountOperation> accountOperations = entityManager.createQuery( "SELECT o FROM AccountOperation o " + "WHERE o.accountIdentifier = :accountIdentifier AND " + "o.date >= :startDate AND o.date <= :endDate ORDER BY o.date"). setParameter("accountIdentifier", accountIdentifier). setParameter("startDate", startDate, TemporalType.TIMESTAMP). setParameter("endDate", endDate, TemporalType.TIMESTAMP). setMaxResults(count+1). setFirstResult(startIndex-1). getResultList(); boolean existMoreAccountOperations = accountOperations.size() == (count+1);

Page-by-Page Iterator (3)


Ejemplo: en la implementacin del caso de uso findAccountOperationsByDate (cont)
/* * Remove the last account operation from the returned list if there * exist more account operations above the specified range. */ if (existMoreAccountOperations) { accountOperations.remove(accountOperations.size()-1); } /* Return AccountOperationChunkVO. */ return new AccountOperationChunkVO( AccountFacadeHelper.toAccountOperationVOs(accountOperations), existMoreAccountOperations);

Page-by-Page Iterator (y 4)
Ejemplo: en la implementacin del caso de uso findAccountOperationsByDate (cont)
El mtodo createQuery devuelve un objeto Query Las cadenas :XXX son parmetros nombrados y se les puede dar valor con los mtodos setParameter
Devuelven el propio objeto Query otra vez, para permitir escribir de manera compacta la construccin de la consulta y su ejecucin En el caso de fechas, hay que usar la variante que recibe un parmetro que especifica si el valor pasado es un DATE, TIME o TIMESTAMP

Page-by-Page Iterator
setMaxResults permite especificar el nmero mximo de resultados setFirstResult permite especificar el ndice del primer resultado (de 0 en adelante) Ambos mtodos devuelven otra vez el objeto Query

getResultList permite ejecutar una consulta de lectura y devuelve una lista con los resultados

SLSBs (1)
Los SLSBs (Stateless Session Beans) son fachadas sin estado Al igual que en MiniPortal, en MiniBank se han definido los interfaces LocalAccountFacade y RemoteAccountFacade, que extienden de AccountFacadeDelegate La clase de implementacin de un SLSB
Se anota con @Stateless (definida en javax.ejb) Tiene que tener un constructor pblico sin argumentos No puede ser final Tiene que implementar los interfaces definidos

Ejemplo en MiniBank: AccountFacadeEJB

SLSBs (2)
AccountFacadeEJB
@Stateless public class AccountFacadeEJB implements LocalAccountFacade, RemoteAccountFacade { @PersistenceContext (unitName=GlobalNames.PERSISTENCE_UNIT) private EntityManager entityManager; public AccountFacadeEJB() {} public AccountVO createAccount(AccountVO accountVO) { // ... } // ... }

SLSBs (3)
Pool de instancias
La implementacin de EJB crea un pool de instancias por cada SLSB Cuando una clase cliente busca un SLSB por JNDI, la implementacin de EJB no crea una instancia asociada al Proxy devuelto Cada vez que la clase cliente realiza una invocacin sobre el Proxy de un SLSB, la peticin se redirige a una de las instancias del pool que no est siendo utilizada en ese momento Un SLSB no puede tener atributos que definan estado propiamente dicho
No puede tener atributos cuyo valor haya que recordar entre invocaciones (e.g. no podra tener un atributo tipo loginName como en el caso de UserFacadeEJB en MiniPortal)

En consecuencia

NOTA: el atributo entityManager en AccountFacadeEJB slo tiene un valor til durante la ejecucin de cada mtodo de la fachada

Recurdese que la implementacin de EJB inicializa un atributo anotado con @PersistenceContext antes de ejecutar cualquier mtodo del Session Bean

SLSBs (y 4)
Efecto de las excepciones del sistema y errores sobre instancias de SLSBs
Al igual que en los SFSBs, adems de hacer un rollback, el contenedor tambin destruye la instancia Pero el hecho de que la instancia se destruya no tiene efecto sobre el cliente, porque cada vez que invoca una operacin, la peticin la procesa una instancia libre del pool

Anda mungkin juga menyukai