Title: Los Enterprise Java Beans son como los Servlets
1Los Enterprise Java Beans son como los Servlets
- Son trozos de código que extienden un servidor
- Viven en un contenedor apropiado
- El contenedor decide cuándo se crean y se
destruyen - No son contactados directamente por el cliente
2Existen 3 Clases principales
- Session Beans
- Implementan procesos, orientados a acciones
(cálculo de un valor) - Entity Beans
- Están asociados a datos persistentes. Representan
una instancia de un dato almacenado - Message Driven Beans
- Parecidos a Session beans pero son despertados
o contactados por mensajes que pueden incluso ser
asínctonos
3Refinando la clasificación
- Session Beans
- Sin estado son contactados una vez por los
clientes, ejecutan una acción y no queda traza de
lo que se hizo - Con estado en una sesión pueden ser
contactados varias veces por el mismo cliente
para desarrollar una conversación. Será
necesario mantener algún tipo de información para
recordar lo que va haciendo el cliente - Entity Beans
- Persistencia controlada por el Bean el
programador debe incluir código de modo de
asegurarse que el enttity bean represente a un
dato en una tabla - Persistencia controlada por el container el
container se preocupa de asociar el bean a un
dato de una tabla
4Qué se necesita escribir para implementar un bean
- Los Archivos Java (programados por el
desarrollador de la aplicación) - La interfaz EJBObject en esta interfaz se
especifican los business methods que implementa
el bean, es decir, todos aquellos métodos que no
tienen que ver con crear, recuperar, destruir o
localizar un bean. Típicamente los que diseña el
programador - La interfaz EJBHome aquí están los métodos para
para crear, destruir y localizar un bean - El EJBean este archivo implementa todos los
métodos del bean. Estos incluyen (de alguna
manera) los declarados por los dos archivos
anteriores y otros métodos propios de la interfaz
bean (obligación de escribirlos, aunque no hagan
nada) - En la última versión hay tembién EJBLocalObject y
EJBLocalHome, para hacer más eficientes las
invocaciones entre beans de un mismo container
5Qué se necesita escribir para implementar un bean
- Los Archivos NO Java (generalmente generados con
ayuda de herramientas del aplication server) - El Deployment descriptor un archivo declarativo
donde se especifican algunas cualidades del bean,
- Bean management and lifecicle requirements si es
un session, entity o message-driven bean - Persistencia (para entity beans) si será CMP o
BMP - Transacciones cómo se manejan las transacciones
- Seguridad control de accesos
- Archivos propios de requeridos por la
implementación del aplication server serán para
sacar provecho de algunas características
específicas de este - Todo esto se debe combinar en un archivo jar, que
se instala en el aplication server en un lugar
específico (estilo servlets)
6Cómo administra el container el cliclo de vida de
los beans
- Los beans son creados y destruidos por el
container. Cuando un bean se levanta con el
container (el bean debe estar ahí cuando se echa
a andar el server) se crean instancias del bean
(bean pool) las cuales son asignadas a los
clientes. Qué bean es entregado a qué cliente lo
decide el container - Si se necesitan más beans estos son creados por
el container (create) - Si hay demasiados estos son destruidos (Remove)
- El container puede decidir además hacer dormir
o despertar a los beans según las necesidades
(activate, passivate) para
7El papel de cada uno de las 3 clases de objetos
- Cuando un cliente desea contactar a un bean
localiza un un ejbHome Object que correspoda al
de un bean deseado. - Este proceso es bien dependiente de las
condiciones locales pero normalmente requiere
hacer un lookup a un servidor de nombres
(normalmente provisto por el servidor de
aplicaciones también) por medio de la API JNDI - Una vez que tiene una referencia a este lo usa
para fabricar un objeto EJB, al cual le aplica
los métodos - El EJBObjet se contactará con un bean adecuado
para que dé el servicio (esto lo hace el
contenedor)
8El papel de cada uno de las 3 clases de objetos
Bean Pool
3 contacta home
ejbHome
cliente
5- retorna referencia
4 crea ejbObject
6 invoca método
1-ubicar
2 retorna referencia
7 contacta bean
ejbObject
Naming
9El Hello World EJB
- Haremos un EJB y un cliente que lo contacte e
invoque el método String hello() que devorverá el
string Hello World - Este será un Session Bean sin estado (obvio)
- El primer archivo es el Hello.java que es la
interfaz que EJBObject que declara los buisness
methods
import javax.ejb. import java.rmi. public
interface Hello extends EJBObject public
string hello() throws RemoteException
10La interfaz EJBObject
- Extiende java.rmi.Remote
- tiene los siguientes métodos
- EJBhome getEJBHome()
- Object getPrimaryKey() //para entity beans
- void remove()
- Handle getHandle()
- boolean isIdentical()
11El Hello World EJB
- El archivo HelloHome.java declara la interfaz con
el home object. En este caso sólo necesitamos
declarar un método para la creación (no necesita
parámetros, es sin estado) - Notar que el método create retorna un objeto del
tipo Hello (EJBObject) que es el que se usará
para invocar los métodos
import javax.ejb. import java.rmi. public
interface HelloHome extends EJBHome Hello
create() throws RemoteException,
CreateException
12La interfaz EJBHome
- Extiende java.rmi.Remote
- tiene los siguientes métodos
- EJBMetaData getEJBMetaData()
- HomeHandle getHomeHandle()
- void remove(Handle handle)
- void remove(Object primaryKey)
13El Hello World EJB
- El archivo HelloBean.java implementa los métodos
necesarios por cada create declarado en Home
debe implementar un ejbCreate con los mismos
parámetros. Además debe implementar los business
methods (hello no más en este caso) y los métodos
propios de los session beans
import javax.ejb. public class HelloBean
extends SessionBean private SessionContext
ctx public void ejbCreate() public String
hello() return(hello world!) public
ejbRemove() //llamado antes de eliminar el
bean public ejbActivate() //llamado al
despertar un bean public ejbPassivate()
//llamado al poner a dormir el bean //en este
caso no nos sirve pero en otros puede
servir //especialmente en los BMP entity bean
public setSessionContext(SessionContext ctx)
this.ctx ctx
14El Deployment descriptor
- Es un archivo xml donde se le dan
declarativamente algunas propiedades al bean,
generado por los tools del aplication developer
lt!DOCTIPE ejb-jar PUBLIC ..... ltejb-jargt
ltenterprise-beansgt ltsessiongt
ltejb-namegtHellolt/ejb-namegt
lthomegtHelloHomelt/homegt
ltremotegtHellolt/remotegt
ltejb-classgtHelloBeanlt/ejb-classgt
ltsession-typegtStatelesslt/session-typegt
lttransaction-typegtContainerlt/transaction-typegt
lt/sessiongt lt/enterprise-beansgt lt/ejb-jargt
15El cliente
import javax.naming. import java.util. import
javax.rmi. public class HelloClient public
static void main(String args) throws Exception
Properties props System.getproperties()
Context ctx new InitialContext(props)
Object obj ctx.lookup(HelloHome)
HelloHome home (HelloHome)PortableRemoteObject.n
arrow
(obj,HelloHome.class) Hello hello
home.create() System.out.println(hello.hell
o()) hello.remove()
- El lookup se realiza en el recurso de naming
(provisto por el container) que se le da al
cliente cuando se lo echa a andar - Cuando el EJB se sube al contenedor, este
registra al Home object (bind) con el seudónimo
HelloHome (nombre de clase)
16Un Session Servlet con Estado
- Cuando un cliente contacta a un stateful servlet
no es tan conveniente que el container los
destruya cuando estime conveniente ya que el
mismo servlet tiene que estar al servicio del
mismo cliente, y el container no puede saber
cuando termina el cliente de contactar al servlet
sino hasta que lo destruye explicitamente. - Tampoco puede mantenerlos indefinidamente en el
container ya que consumen recursos - La solución pasa por pasivarlos y activarlos
- Pasivarlos pasan de emoria principal a
secundaria - Activarlos pasan de memoria secundaria a
principal (swapping)
17Un Session Servlet con Estado
- El container implementa una política de
pasivacion-activación por ejemplo, Least Used
reciently - Un bean involucrado en una transaccón o sirviendo
a un cliente no puede ser pasivado - Se usa serialización
- el método ejbPassivate es llamado antes de copiar
el bean al disco - el método ejbActivate es llamado cuando se activa
- En cada método se liberan/recuperan recursos que
no se pueden serializar por ej. conexiones a
bases de datos, archivos abiertos (que pasa si
esta leyendo en medio del archivo), conexiones a
sockets
18El Count Bean
- Tendrá un método count() que incrementa una
variable llamada val - Esta será la variable que determinará que es un
bean de estado
//interfaz remota import javax.ejb. import
java.rmi. public interface Count extends
EJBObject public int count() throws
RemoteException
//el home interface import javax.ejb. import
java.rmi. public interface CountHome extends
EJBHome Count create(int val) throws
RemoteException, CreateException
19El Count Bean
import javax.ejb. public class CountBean
extends SessionBean public int val private
SessionContext ctx public int count()
return val public void ejbCreate(int
val) this.val val public ejbRemove()
//llamado antes de eliminar el bean public
ejbActivate() //llamado al despertar un
bean public ejbPassivate() //llamado al poner
a dormir el bean public setSessionContext(Session
Context ctx) this.ctx ctx
20El Count Bean
lt!DOCTIPE ejb-jar PUBLIC ..... ltejb-jargt
ltenterprise-beansgt ltsessiongt
ltejb-namegtCountlt/ejb-namegt
lthomegtCountHomelt/homegt
ltremotegtCountlt/remotegt
ltejb-classgtCountBeanlt/ejb-classgt
ltsession-typegtStatefullt/session-typegt
lttransaction-typegtContainerlt/transaction-typegt
lt/sessiongt lt/enterprise-beansgt lt/ejb-jargt
21Estados de un Bean
Cliente invoca create en un home Interface
Cliente llama a remove() en el ejbObject o se
le da un timeout al cliente
No existe
El container llega a un límite de su capacidad
swapping
1- Class.newInstance() 2- setSessionContext() 3-
ejbCreate(...)
ejbRemove()
Timeout del cleinte
ejbActivate()
Activo
Pasivo
ejbPassivate()
Liente llama a un método del Bean pasivado
22Los Entity beans
- Un bean representa a un dato (fila) en una base
de datos - Hay que pensar en ellos como si fueran uno solo
con el dato en memoria secundaria - Debe existir un mecanismo para automáticamente
transferir los datos de la memoria secundaria al
EJB y vice-versa - Esto se hace a través de llamadas a los métodos
ejbLoad() y ejbStore() - Estos métodos son llamados por el container
cuando estima que es necesario - distintos beans pueden representar al mismo dato
en disco - ejbActivate() y ejbPassivate() se llaman cuando
un entity bean es puesto/sacado de un pool de
beans, por lo que hay que programas la
adquisición y liberación de reucursos - Como además se debe guardar el estado del bean en
memoria secundaria, por lo cual se llama siempre
a ejbStore abtes de pasivar y a ejbLoad antes de
activar
23Las 2 maneras de lograr persistencia de los beans
- En un bean-manajed persistence entity bean el
programador debe escribir las instrucciones para
que las variables del entity bean sean las
correspondientes a un dato en una base de datos
(saving, loading, and finding) - Estas instrucciones van en los métodos de
creación (ejbCreate(...)), destrucción
(ejbRemove()), localización (ejbFind(...)), carga
(ejbload()) y almacenamiento (ejbStore()) - Esto generalmente se hace via instrucciones JDBC
- En los container-managed persistence beans de
esto se encarga el container, sólo basta dar
algunas directrices para la localización de los
datos en un archivo especial (según yo, esto
sería una de las gracias más grandes de j2ee)
24Creación y destrucción de Beans
- Cuando un entity bean es creado por una llamada
al método ejbCreate se debe crear también este
dato en la base de datos, si se trata de un
bean-managed persistence bean, aquí se deben
programar las instruccónes SQL para insertar una
fila en una tabla - De la misma manera, cuando un entity bean es
removido, se llama a ejbRemove y aquí se debe
programas la instrucción SQL que borre la fila
correspondiente - A cada clase de entity bean que se crea hay que
asociarle un objeto que represente la clave
primaria de ese tipo de objeto (por ejemplo un
string. Por convención se usa el nombre del bean
terminado en PK (por ejemplo CuentaPK) - El método ejbCreate de un entity bean debe
devolver un siempre un objeto de este tipo luego
de haber creado el dato
25Esquema de creación de un entity bean
1- create()
2- ejbCreate()
cliente
Home
4- retorna una referencia al EJB object
Bean
4- retorna un objeto que representa la
clave primaria del ejb creado
5- creación del objeto EJB
3- se crea el dato en la base de datos
EJB Object
Base de Datos
CONTAINER
26Creación y destrucción de Beans
- Si, por ejemplo, tenemos un Bean que se llamará
Account, el home object será de la clase
AccountHome, el EJB Object se llamará Account y
el EJBean se llamará AccountBean y el objeto que
representa a la clave primaria se llamará
AccountPK - Para un un método de creación en el AccountHome
de la siguiente forma - public Account create(String id, String nomb)...
- le corresponderá un método en el AccountBean de
las siguiente forma - public AccountPK ejbCreate(String id, String
nomb).. - El método remove() se puede aplicar tanto al EJB
object como al home object, en ambos casos se
terminará llamando a ejbRemove() que debe hacerse
cargo de borrar el dato de la base de datos
27Encontrando Beans (en BMP)
- Como sucede en el manejo directo de bases de
datos, muchas veces vamos a querer encontrar
beans, es decir, tener referencia a uno o mas
beans que reflejen datos que ya se encuantran en
la base de datos - Estas se hacen por medio de los métodos findXXX
en el home y su correspondiente ejbFindXXX en el
Bean - Ejemplo para uno home retorna un EJBobject y el
bean un PrimaryKey - public Account findAnAccountFor(String name) en
el home - public AccountPK ejbFindAnAccountFor(String name)
en el Bean - Ejemplo para varios home retorna una colección
de EJB y el Bean de keys - public Collection findAllAccountsFor(String name)
en el home - public Collection ejbFindAllAccountsFor(String
name) en el Bean - SIEMPRE debe implementarse al menos el siguiente
- public Account findByPrimaryKey(AccountPK key)
- public AccountPK ejbFindByPrimaryKey(AccountPK
key)
28El Contexto
- El objeto Context es pasado al bean por el
container cuando llama a setSessionContext o
setEntityContext según corresponda. Este contiene
información acerca del contexto del bean - Si el bean lo necesita, debería mantener una
referencia (como se hizo en el primer ejemplo) - Los métodos que se pueden llamar son
- getEJBObject() retorna el EJBObject asociado al
bean - getPrimaryKey() sólo para entity beans (obvio),
retorna el key del dato asociado a esta
instancia. Esto es necesario porque un bean no
sabe en principio a que dato está asociado (el
EJBObject si) - Es muy útil en los bean managed persistence
entity beans cuando se programa EjbLoad() para
saber qué dato hay que recuperar de la base de
datos (con un select) y asociarlo al bean.
También para ejbRemove() para saber qué fila de
la tabla se debe borrar en la base de datos
29La Interfaz entity bean
- Cuando se programa un Entity bean hay que
programar los siguientes métodos, (aparte de los
business methods) - setEntityContext(EntityContext ctx)
- unsetEntityContext() se llama antes de destruirse
el bean - ejbFindXXX(...) para encontrar datos según lo
especificado en el home - ejbHomeXXX(...) para business methods no
asociados a datos (como session) - ejbCreate(...) según lo especificado en el home
- ejbRemove()
- ejbActivate()
- ejbPassivate()
- ejbLoad()
- ejbStore()
30El EJBObject para cuentas Account
import javax.ejb. import java.rmi. public
interface Account extends EJBObject public
void depositar(int monto) throws
RemoteException public boolean girar(int monto)
throws RemoteException public int getSaldo()
throws RemoteException public String getOwner()
throws RemoteException public void
setOwner(String name) throws RemoteException pub
lic String getAccountID() throws
RemoteException public void setAccountID(String
ID) throws RemoteException
31El Home Interface AccountHome
import java.util.Collection import
javax.ejb. import java.rmi. public interface
AccountHome extends EJBHome Account
create(String ID, String name) throws
RemoteException, CreateException public Account
findByPrimaryKey(AccountPK ac) throws
RemoteException, FinderException public
Collection findByOwnerName(String name)
throws RemoteException, FinderException publ
ic double getTotelBankValue() throws
RemoteException
32El Primary Key AccountPK
import java.io.Serializable public class
AccountPK implements Serializable public
String accountID public AccountPK(String id)
accountID id public AccountPK()
public toString() //requerido !!!
return accountID public hashCode()
// requerido !!! return accountID.hashCode()
public equals(Object account) //
requerido !!! return ((AccountPK)account).acc
ountID.equals(accountID)
33El Bean AccountBean (1)
import java.sql. import java.naming. import
javax.ejb. import javax.util. public class
AccountBean implements EntityBean
EntityContext ctx String accountID String
owner int saldo public void depositar(int
monto) saldo saldo monto
public boolean girar(int monto) if (monto
gt saldo) saldo saldo - monto return
true return false ....
34El Bean AccountBean (2)
... public int getSaldo() return
saldo public String getOwner() return
owner public void setOwner(String name)
owner name public String
getAccountID() return accountID public
void setAccountID(String id) sccountID
id ...
35El Bean AccountBean (3)
... public Connection getConnection() throws
Exception Class.forName(com.informix.jdbc.Ifx
Driver) String url jdbcinformix-sqli//
hostname/CGE_HOLDINFORMIXSERVERservername
Connection con DriverManager.getConnec
tion(url,nbaloian,123) return
con public int ejbHomeGetTotalBankValu
e() try Connection conn
getConnection() PreparedStatement psmt
conn.prepareStatement( select sum(saldo) as
total from accaounts) ResultSet rs
psmt.executeQuery() psmt.close()
conn.close() return rs.getInt(total)
catch (Exception e) //arreglar el pastel
...
36El Bean AccountBean (4)
... public void ejbActivate() // es
necesario escribirla public void ejbPassivate()
// igual public void ejbRemove()
AccountPK pk (AccountPk) ctx.getPrimaryKey()
String id pk.acountID try
Connection conn getconnection()
PreparedStatement psmt conn.prepareStatement(
delete from accounts where id ?)
psmt.setString(1,id) if(psmt.executeUpdate()
0) System.out.println(problemas)
psmt.close() conn.close() catch (Exception
e) e.printStackTrace() ...
37El Bean AccountBean (5)
... public void ejbLoad() AccountPK pk
(AccountPk) ctx.getPrimaryKey() String id
pk.acountID try Connection conn
getconnection() PreparedStatement psmt
conn.prepareStatement( select ownerName,
balance from accounts where id ?)
psmt.setString(1,id) ResultSet rs
psmt.executeQuery() rs.next()
ownerName rs.getString(ownername) saldo
rs.getInt(saledo) psmt.close()
conn.close() catch (Exception e)
e.printStackTrace() ...
38El Bean AccountBean (6)
... public void ejbStore() try
Connection conn getconnection()
PreparedStatement psmt conn.prepareStatement(
update accounts set ownerName ?, saldo
? where id ?) psmt.setString(1,owne
r) psmt.setString(2,saldo)
psmt.setString(3,accountID)
psmt.executeUpdate() psmt.close()
conn.close() catch (Exception e)
e.printStackTrace() public
setEntityContext(EntityContext ctx) this.ctx
ctx public unsetEntityCOntext()
this.ctx null ...
39El Bean AccountBean (7)
... public AccountPK ejbCreate(String id,
String name) throws CreateException
accountID id ownerName name saldo
0 try Connection conn
getconnection() PreparedStatement psmt
conn.prepareStatement( insert into
accounts (id, ownerName, saldo) values
(?,?,?)) psmt.setString(1,accountID)
psmt.setString(2,owner)
psmt.setString(3,saldo) psmt.executeUpdate(
) psmt.close() conn.close() return
new AccountPK(accountID) catch (Exception
e) e.printStackTrace() ...
40El Bean AccountBean (8)
... public AccountPK ejbPostCreate(String id,
String name) throws CreateException
// por cada create hay que escribir un
PostCreate que se llama // justo después de la
creación public AccountPK ejbFindByPrimaryKey(A
ccountPK key) throws FinderException
try Connection conn getConnection()
PreparedStatement psmt conn.prepareStatement(
select id from account where id
?) psmt.setString(1,key.toString()) Resul
tSet rs psmt.executeQuery() rs.next() ps
mt.close() conn.close() return
key() catch (Exception e) .... ...
41El Bean AccountBean (9)
... public AccountPK ejbFindByOwnerName(Strin
g n) throws FinderException try
Connection conn getConnection() Prepare
dStatement psmt conn.prepareStatement( selec
t id from account where ownerName
?) psmt.setString(1,n) ResultSet rs
psmt.executeQuery() Vector v new
Vector() while (rs.next()) String id
rs.getString(id) v.addElement(new
AccountPK(id)) psmt.close()
conn.close() return v catch (Exception e)
.... //por fin !!! ...
42El Deployment descriptor
lt!DOCTIPE ejb-jar PUBLIC ..... ltejb-jargt
ltenterprise-beansgt ltentitygt
ltejb-namegtAccountlt/ejb-namegt
lthomegtAccountHomelt/homegt
ltremotegtAccountlt/remotegt
ltejb-classgtAccountBeanlt/ejb-classgt
ltpersistence-typegtBeanlt/persistence-typegt
ltprimary-key-classgtAccountPKlt/
primary-key-class gt ltreentrantgtfalselt/reentrantgt
ltresource-refgt ltres-ref-namegtjdbc/ejPoollt/res
-ref-namegt ltres-typegtjavax.sql.DataSourcelt/res
-typegt ltres-authgtContainerlt/res-authgt lt/resou
rce-refgt lt/entitygt lt/enterprise-beansgt
ltassembly-descriptorgt ....para
transacciones... lt/assembly-descriptorgtl lt/ejb
-jargt
43Los CMP Entity Beans
- La idea principal es no tener que escribir ningun
código de persistencia con la base de datos - Mucho del código migra del Bean al Deployment
descriptor (pero muy simplificado) - Juega un papel importante el EJB-QL, que es un
lenguaje estilo SQL orientado a objetos con el
cual se especifican muchas cosas.
44Principalen diferencias con BMP
- Lo que uno escribe es una superclase del bean,
que será extendida automáticamente por el sistema
para añadirle el código de persistencia - Por esto, la declaración de un CMP es abstract
!!! - No se declaran Campos del bean (variables). Estas
van especificadas en el Deployment descriptor y
aparecen en la clase extendida - Por eso mismo, tampoco se escriben los métodos
set/get finales, sólo se declaran en forma
abstracta (como en una interfaz) - los métodos find también se declaran en horma
abstracta. La forma de cómo localizan los beans
se da por medio del EJB-QL en el deployment
descriptor - también se pueden definir métodos abstractos
ejbSelectXXX que serán usados al interior del
bean. Estos no sólo pueden ubicar beans sino que
campos de ellos (por ejemplo, el saldo de todas
las cuentas que pertenecen a un owner dado)
45Métodos a declarar en el Bean
- setEntityContext() igual que en los BMP
- ejbFindXXX(...) se declaran en forma abstracta,
la forma cómo deben trabajar se especifica en el
deployment descriptor con el EJB-QL - ejbSelectXXX(...) igual que para el punto
anterior, pero estos no son visibles desde el
EJBObject, son par auso interno del bean - ejbHomeXXX(...) para declaración de métodos
estáticos - ejbCreate(...) no se debe escribir código que
inserta datos en la base de datos. Sólo se usan
los métodos setXXX para poner el valor a los
campos según lo pasado por los parámetros (o no) - ejbPostCreate(...) igual que en BMP
- ejbActivate() igual que en BMP
- ejbLoad() no hacer cosas que tengan que ver con
cargar el dato, esto lo implementa el container.
(pero adquirir recursos) - ejbStore() idem anterior (pero liberar recursos)
- ejbRemove() idem anterior
- ejbUnsetEntityContent() igual que para BMP
46El EJBObject para Product
import javax.ejb. import java.rmi. public
interface Product extends EJBObject public
String getName() throws RemoteException
public void setName(String name) throws
RemoteException public String
getDescription() throws RemoteException
public void setDescription(String desc) throws
RemoteException public double getBasePrice()
throws RemoteException public void
setBasePrice(double price) throws
RemoteException public String getProductID()
throws RemoteException public void
setProductID(String id) throws RemoteException
47El Home Interface ProductHome
import java.util.Collection import
javax.ejb. import java.rmi. public interface
ProductHome extends EJBHome Product
create(String ProductID, String name, String
description, double price) throws
RemoteException, CreateException poublic
Product findByPrimaryKey(ProductPK key)
throws RemoteException, FinderException publ
ic Collection findByName(String name) throws
RemoteException, FinderException public
Collection findByDescription(String desc)
throws RemoteException, FinderException publ
ic Collection findByBasePrice(double price)
throws RemoteException, FinderException publ
ic Collection findExpensiveProducts(double price)
throws RemoteException, FinderException publ
ic Collection findCheapProducts(double price)
throws RemoteException, FinderException publ
ic Collection findAll(String name) throws
RemoteException, FinderException
48El Primary Key ProductPK
import java.io.Serializable public class
ProductPK implements Serializable public
String productID public ProductPK(String id)
productID id public productID()
public toString() //requerido !!!
return productID public hashCode()
// requerido !!! return productID.hashCode()
public equals(Object prod) // requerido
!!! return ((AccountPK)prod).
productID.equals(productID)
49El Bean ProductBean (1)
import java.sql. public abstract class
ProducttBean implements EntityBean
EntityContext ctx public abstract String
getName() public abstract void setName(String
name) public abstract String getDescription()
public abstract void setDescription(String
desc) public abstract double getBasePrice() pu
blic abstract void setBasePrice(double
price) public abstract String
getProductID() public abstract void
setProductID(String id) public void
ejbActivate() public void ejbPasivate()
public void ejbRemove() public void
ejbLoad() public void ejbStore() ....
50El Bean ProductBean (2)
... public void setEntityContext(EntityContext
ctx) this.ctx ctx public void
unsetEntityContext() this.ctx null public
void ejbPostCreate(String id, String
name String desc, double price) public
String Create(String id, String name String
desc, double price) setProductID(id) setNam
e(name) setDescription(desc) setBasePrice(pr
ice) return id //sorry esta en el libro
51El Deployment descriptor es bastante grande,
claro
lt!DOCTIPE ejb-jar PUBLIC ..... ltejb-jargt
ltenterprise-beansgt ltentitygt
ltejb-namegtProductlt/ejb-namegt
lthomegtProductHomelt/homegt
ltremotegtProductlt/remotegt
ltejb-classgtProductBeanlt/ejb-classgt
ltpersistence-typegtContainerlt/persistence-typegt
ltprimary-key-classgtProductPKlt/
primary-key-class gt ltreentrantgtfalselt/reentrantgt
ltcmp-versiongt2.xlt/cmp-versiongt ltabstract-schema-
namegtProductBeanlt/abstract-schema-namegt ltcmp-fie
ldgt ltfield-namegtproductIDlt/field-namegt lt/cmp-
fieldgt ltcmp-fieldgt ltfield-namegtnamelt/field-na
megt lt/cmp-fieldgt ltcmp-fieldgt
ltfield-namegtdescriptionlt/field-namegt lt/cmp-fieldgt
ltcmp-fieldgt ltfield-namegtbasePricelt/field-nam
egt lt/cmp-fieldgt
52El Deployment descriptor es bastante grande,
claro
ltquerygt ltquery-methodgt
ltmethod-namegtfindByNamelt/method-namegt
ltmethod-paramsgt ltmethod-paramgtjava.lang.
Stringlt/method-paramgt ltmethod-paramsgt
ltquery-methodgt ltejb-sqlgt
lt!CDATASELECT OBJECT (a) FROM ProducBean AS a
WHERE name ?1gt lt/ejb-sqlgt lt/querygt
ltquerygt ltquery-methodgt
ltmethod-namegtfindExpensiveProductslt/method-namegt
ltmethod-paramsgt
ltmethod-paramgtdoublelt/method-paramgt
ltmethod-paramsgt ltquery-methodgt
ltejb-sqlgt lt!CDATASELECT OBJECT (a)
FROM ProducBean AS a WHERE basePrice gt ?1gt
lt/ejb-sqlgt lt/querygt lt/entitygt lt/enterprise-bean
sgt
53El Deployment descriptor es bastante grande,
claro
ltassembly-descriptorgt ....para
transacciones... lt/assembly-descriptorgtl lt/ejb
-jargt