Los Enterprise Java Beans son como los Servlets
Los 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
Existen 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
Refinando 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
Qué 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 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 EJBLocal. Object y EJBLocal. Home, para hacer más eficientes las invocaciones entre beans de un mismo container
Qué 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)
Có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
El papel de cada uno de las 3 clases de objetos • Cuando un cliente desea contactar a un bean localiza un un ejb. Home 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)
El papel de cada uno de las 3 clases de objetos Bean Pool 3 contacta home cliente ejb. Home 5 - retorna referencia 6 invoca método 4 crea ejb. Object 1 -ubicar 2 retorna referencia Naming ejb. Object 7 contacta bean
El 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 Remote. Exception; }
La interfaz EJBObject • Extiende java. rmi. Remote • tiene los siguientes métodos – – – EJBhome get. EJBHome() Object get. Primary. Key() //para entity beans void remove() Handle get. Handle() boolean is. Identical()
El Hello World EJB • El archivo Hello. Home. 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) import javax. ejb. *; import java. rmi. *; public interface Hello. Home extends EJBHome { Hello create() throws Remote. Exception, Create. Exception; } • Notar que el método create retorna un objeto del tipo Hello (EJBObject) que es el que se usará para invocar los métodos
La interfaz EJBHome • Extiende java. rmi. Remote • tiene los siguientes métodos – – EJBMeta. Data get. EJBMeta. Data() Home. Handle get. Home. Handle() void remove(Handle handle) void remove(Object primary. Key)
El Hello World EJB • El archivo Hello. Bean. java implementa los métodos necesarios: por cada create declarado en Home debe implementar un ejb. Create 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 Hello. Bean extends Session. Bean { private Session. Context ctx; public void ejb. Create() {} public String hello() { return(“hello world!”); } public ejb. Remove() {} //llamado antes de eliminar el bean public ejb. Activate(){} //llamado al despertar un bean public ejb. Passivate(){} //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 set. Session. Context(Session. Context ctx) { this. ctx = ctx; } }
El Deployment descriptor • Es un archivo xml donde se le dan declarativamente algunas propiedades al bean, generado por los tools del aplication developer <!DOCTIPE ejb-jar PUBLIC. . . <ejb-jar> <enterprise-beans> <session> <ejb-name>Hello</ejb-name> <home>Hello. Home</home> <remote>Hello</remote> <ejb-class>Hello. Bean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> </ejb-jar>
El cliente import javax. naming. *; import java. util. *; import javax. rmi. *; public class Hello. Client { public static void main(String args[) throws Exception { Properties props = System. getproperties(); Context ctx = new Initial. Context(props); Object obj = ctx. lookup(“Hello. Home”); Hello. Home home = (Hello. Home)Portable. Remote. Object. narrow (obj, Hello. Home. class); Hello hello = home. create(); System. out. println(hello()); 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 “Hello. Home” (nombre de clase)
Un 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)
Un Session Servlet con Estado • El container implementa una “política” de pasivacionactivació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 ejb. Passivate es llamado antes de copiar el bean al disco • el método ejb. Activate 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
El 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 Remote. Exception; } //el home interface import javax. ejb. *; import java. rmi. *; public interface Count. Home extends EJBHome { Count create(int val) throws Remote. Exception, Create. Exception; }
El Count Bean import javax. ejb. *; public class Count. Bean extends Session. Bean { public int val; private Session. Context ctx; public int count() { return ++val; } public void ejb. Create(int val) { this. val = val; } public } } ejb. Remove() {} //llamado antes de eliminar el bean ejb. Activate(){} //llamado al despertar un bean ejb. Passivate(){} //llamado al poner a dormir el bean set. Session. Context(Session. Context ctx) { this. ctx = ctx;
El Count Bean <!DOCTIPE ejb-jar PUBLIC. . . <ejb-jar> <enterprise-beans> <session> <ejb-name>Count</ejb-name> <home>Count. Home</home> <remote>Count</remote> <ejb-class>Count. Bean</ejb-class> <session-type>Stateful</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> </ejb-jar>
Estados de un Bean Cliente invoca create en un home Interface Cliente llama a remove() en el ejb. Object o se le da un timeout al cliente No existe El container llega a un límite de su capacidad: swapping 1 - Class. new. Instance() 2 - set. Session. Context() 3 - ejb. Create(. . . ) ejb. Remove() Timeout del cleinte ejb. Activate() Activo Pasivo ejb. Passivate() Liente llama a un método del Bean pasivado
Los 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 ejb. Load() y ejb. Store() • Estos métodos son llamados por el container cuando estima que es necesario • distintos beans pueden representar al mismo dato en disco • ejb. Activate() y ejb. Passivate() 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 ejb. Store abtes de pasivar y a ejb. Load antes de activar
Las 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 (ejb. Create(. . . )), destrucción (ejb. Remove()), localización (ejb. Find(. . . )), carga (ejbload()) y almacenamiento (ejb. Store()) • 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 j 2 ee)
Creación y destrucción de Beans • Cuando un entity bean es creado por una llamada al método ejb. Create 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 ejb. Remove 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 Cuenta. PK) • El método ejb. Create de un entity bean debe devolver un siempre un objeto de este tipo luego de haber creado el dato
Esquema de creación de un entity bean 1 - create() cliente 2 - ejb. Create() Home 4 - retorna una referencia al EJB object 5 - creación del objeto EJB 4 - retorna un objeto que representa la clave primaria del ejb creado EJB Object CONTAINER Bean 3 - se crea el dato en la base de datos Base de Datos
Creación y destrucción de Beans • Si, por ejemplo, tenemos un Bean que se llamará Account, el home object será de la clase Account. Home, el EJB Object se llamará Account y el EJBean se llamará Account. Bean y el objeto que representa a la clave primaria se llamará Account. PK • Para un un método de creación en el Account. Home de la siguiente forma: – public Account create(String id, String nomb). . . • le corresponderá un método en el Account. Bean de las siguiente forma: – public Account. PK ejb. Create(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 ejb. Remove() que debe hacerse cargo de borrar el dato de la base de datos
Encontrando 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 find. XXX en el home y su correspondiente ejb. Find. XXX en el Bean • Ejemplo para uno: home retorna un EJBobject y el bean un Primary. Key – public Account find. An. Account. For(String name) en el home – public Account. PK ejb. Find. An. Account. For(String name) en el Bean • Ejemplo para varios: home retorna una colección de EJB y el Bean de keys – public Collection find. All. Accounts. For(String name) en el home – public Collection ejb. Find. All. Accounts. For(String name) en el Bean • SIEMPRE debe implementarse al menos el siguiente – public Account find. By. Primary. Key(Account. PK key) – public Account. PK ejb. Find. By. Primary. Key(Account. PK key)
El Contexto • El objeto Context es pasado al bean por el container cuando llama a set. Session. Context o set. Entity. Context 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: – get. EJBObject() retorna el EJBObject asociado al bean – get. Primary. Key() 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 Ejb. Load() para saber qué dato hay que recuperar de la base de datos (con un select) y asociarlo al bean. También para ejb. Remove() para saber qué fila de la tabla se debe borrar en la base de datos
La Interfaz entity bean • Cuando se programa un Entity bean hay que programar los siguientes métodos, (aparte de los “business methods) – – – – – set. Entity. Context(Entity. Context ctx) unset. Entity. Context() se llama antes de destruirse el bean ejb. Find. XXX(. . . ) para encontrar datos según lo especificado en el home ejb. Home. XXX(. . . ) para business methods no asociados a datos (como session) ejb. Create(. . . ) según lo especificado en el home ejb. Remove() ejb. Activate() ejb. Passivate() ejb. Load() ejb. Store()
El EJBObject para cuentas Account import javax. ejb. *; import java. rmi. *; public interface Account extends EJBObject { public void depositar(int monto) throws Remote. Exception; public boolean girar(int monto) throws Remote. Exception; public int get. Saldo() throws Remote. Exception; public String get. Owner() throws Remote. Exception; public void set. Owner(String name) throws Remote. Exception; public String get. Account. ID() throws Remote. Exception; public void set. Account. ID(String ID) throws Remote. Exception; }
El Home Interface Account. Home import public } java. util. Collection; javax. ejb. *; java. rmi. *; interface Account. Home extends EJBHome { Account create(String ID, String name) throws Remote. Exception, Create. Exception; public Account find. By. Primary. Key(Account. PK ac) throws Remote. Exception, Finder. Exception; public Collection find. By. Owner. Name(String name) throws Remote. Exception, Finder. Exception; public double get. Totel. Bank. Value() throws Remote. Exception;
El Primary Key Account. PK import java. io. Serializable; public class Account. PK implements Serializable { public String account. ID; public Account. PK(String id) { account. ID = id; } public Account. PK() {} public to. String() { //requerido !!! return account. ID; } public hash. Code() { // requerido !!! return account. ID. hash. Code(); } public equals(Object account) { // requerido !!! return ((Account. PK)account). account. ID. equals(account. ID); } }
El Bean Account. Bean (1) import java. sql. *; java. naming. *; javax. ejb. *; javax. util. *; public class Account. Bean implements Entity. Bean { Entity. Context ctx; String account. ID; String owner; int saldo; public void depositar(int monto) { saldo = saldo + monto; } public boolean girar(int monto) { if (monto >= saldo) { saldo = saldo - monto; return true; } return false; }. .
El Bean Account. Bean (2). . . public int get. Saldo() { return saldo; } public String get. Owner() { return owner; } public void set. Owner(String name) { owner = name; } public String get. Account. ID() { return account. ID; } public void set. Account. ID(String id) { sccount. ID = id }. . .
El Bean Account. Bean (3). . . public Connection get. Connection() throws Exception { Class. for. Name(“com. informix. jdbc. Ifx. Driver”); String url = “jdbc: informix-sqli: //”+ “hostname/CGE_HOLD: INFORMIXSERVER=servername”; Connection con = Driver. Manager. get. Connection(url, ”nbaloian”, ” 123”); return con; } public int ejb. Home. Get. Total. Bank. Value() { try { Connection conn = get. Connection(); Prepared. Statement psmt = conn. prepare. Statement( “select sum(saldo) as total from accaounts”); Result. Set rs = psmt. execute. Query(); psmt. close(); conn. close(); return rs. get. Int(“total”); } catch (Exception e) { //arreglar el pastel } }
El Bean Account. Bean (4). . . public void ejb. Activate() { public void ejb. Passivate() { } // es necesario escribirla } // igual public void ejb. Remove() { Account. PK pk = (Account. Pk) ctx. get. Primary. Key(); String id = pk. acount. ID; try { Connection conn = getconnection(); Prepared. Statement psmt = conn. prepare. Statement( “delete from accounts where id = ? ”); psmt. set. String(1, id); if(psmt. execute. Update() == 0) System. out. println(“problemas”); psmt. close(); conn. close(); } catch (Exception e) { e. print. Stack. Trace()} } . . .
El Bean Account. Bean (5). . . public void ejb. Load() { Account. PK pk = (Account. Pk) ctx. get. Primary. Key(); String id = pk. acount. ID; try { Connection conn = getconnection(); Prepared. Statement psmt = conn. prepare. Statement( “select owner. Name, balance from accounts where id = ? ”); psmt. set. String(1, id); Result. Set rs = psmt. execute. Query(); rs. next(); owner. Name = rs. get. String(“ownername”); saldo = rs. get. Int(“saledo”); psmt. close(); conn. close(); } catch (Exception e) { e. print. Stack. Trace()} }. . .
El Bean Account. Bean (6) . . . public void ejb. Store() { try { Connection conn = getconnection(); Prepared. Statement psmt = conn. prepare. Statement( “update accounts set owner. Name = ? , saldo = ? ”+ “where id = ? ”); psmt. set. String(1, owner); psmt. set. String(2, saldo); psmt. set. String(3, account. ID); psmt. execute. Update(); psmt. close(); conn. close(); } catch (Exception e) { e. print. Stack. Trace()} } public set. Entity. Context(Entity. Context ctx) { this. ctx = ctx; } public }. . . unset. Entity. COntext() { this. ctx = null;
El Bean Account. Bean (7) . . . public Account. PK ejb. Create(String id, String name) throws Create. Exception { account. ID = id; owner. Name = name; saldo = 0; try { Connection conn = getconnection(); Prepared. Statement psmt = conn. prepare. Statement( “insert into accounts (id, owner. Name, saldo) values (? , ? )”); psmt. set. String(1, account. ID); psmt. set. String(2, owner); psmt. set. String(3, saldo); psmt. execute. Update(); psmt. close(); conn. close(); return new Account. PK(account. ID); } catch (Exception e) { e. print. Stack. Trace()} }. . .
El Bean Account. Bean (8) . . . public Account. PK ejb. Post. Create(String id, String name) throws Create. Exception { } // por cada create hay que escribir un Post. Create que se llama // justo después de la creación public Account. PK ejb. Find. By. Primary. Key(Account. PK key) throws Finder. Exception { try { Connection conn = get. Connection(); Prepared. Statement psmt = conn. prepare. Statement( “select id from account where id = ? ”); psmt. set. String(1, key. to. String()); Result. Set rs = psmt. execute. Query(); rs. next(); psmt. close(); conn. close(); return key(); catch (Exception e) {. . } }. . .
. . . El Bean Account. Bean (9) public Account. PK ejb. Find. By. Owner. Name(String n) throws Finder. Exception { try { Connection conn = get. Connection(); Prepared. Statement psmt = conn. prepare. Statement( “select id from account where owner. Name = ? ”); psmt. set. String(1, n); Result. Set rs = psmt. execute. Query(); Vector v = new Vector(); while (rs. next()) { String id = rs. get. String(“id”); v. add. Element(new Account. PK(id)); } psmt. close(); conn. close(); return v; catch (Exception e) {. . } } } //por fin !!!. . .
El Deployment descriptor <!DOCTIPE ejb-jar PUBLIC. . . <ejb-jar> <enterprise-beans> <entity> <ejb-name>Account</ejb-name> <home>Account. Home</home> <remote>Account</remote> <ejb-class>Account. Bean</ejb-class> <persistence-type>Bean</persistence-type> <primary-key-class>Account. PK</ primary-key-class > <reentrant>false</reentrant> <resource-ref> <res-ref-name>jdbc/ej. Pool</res-ref-name> <res-type>javax. sql. Data. Source</res-type> <res-auth>Container</res-auth> </resource-ref> </entity> </enterprise-beans> <assembly-descriptor>. . para transacciones. . . </assembly-descriptor>l </ejb-jar>
Los 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.
Principalen 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 ejb. Select. XXX 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)
Métodos a declarar en el Bean • set. Entity. Context() igual que en los BMP • ejb. Find. XXX(. . . ) se declaran en forma abstracta, la forma cómo deben trabajar se especifica en el deployment descriptor con el EJB-QL • ejb. Select. XXX(. . . ) igual que para el punto anterior, pero estos no son visibles desde el EJBObject, son par auso interno del bean • ejb. Home. XXX(. . . ) para declaración de métodos “estáticos” • ejb. Create(. . . ) no se debe escribir código que inserta datos en la base de datos. Sólo se usan los métodos set. XXX para poner el valor a los campos según lo pasado por los parámetros (o no) • ejb. Post. Create(. . . ) igual que en BMP • ejb. Activate() igual que en BMP • ejb. Load() no hacer cosas que tengan que ver con cargar el dato, esto lo implementa el container. (pero adquirir recursos) • ejb. Store() idem anterior (pero liberar recursos) • ejb. Remove() idem anterior • ejb. Unset. Entity. Content() igual que para BMP
El EJBObject para Product import javax. ejb. *; import java. rmi. *; public interface Product extends EJBObject { public String get. Name() throws Remote. Exception; public void set. Name(String name) throws Remote. Exception; public String get. Description() throws Remote. Exception; public void set. Description(String desc) throws Remote. Exception; public double get. Base. Price() throws Remote. Exception; public void set. Base. Price(double price) throws Remote. Exception; public String get. Product. ID() throws Remote. Exception; public void set. Product. ID(String id) throws Remote. Exception; }
El Home Interface Product. Home import public } java. util. Collection; javax. ejb. *; java. rmi. *; interface Product. Home extends EJBHome { Product create(String Product. ID, String name, String description, double price) throws Remote. Exception, Create. Exception; poublic Product find. By. Primary. Key(Product. PK key) throws Remote. Exception, Finder. Exception; public Collection find. By. Name(String name) throws Remote. Exception, Finder. Exception; public Collection find. By. Description(String desc) throws Remote. Exception, Finder. Exception; public Collection find. By. Base. Price(double price) throws Remote. Exception, Finder. Exception; public Collection find. Expensive. Products(double price) throws Remote. Exception, Finder. Exception; public Collection find. Cheap. Products(double price) throws Remote. Exception, Finder. Exception; public Collection find. All(String name) throws Remote. Exception, Finder. Exception;
El Primary Key Product. PK import java. io. Serializable; public class Product. PK implements Serializable { public String product. ID; public Product. PK(String id) { product. ID = id; } public product. ID() {} public to. String() { //requerido !!! return product. ID; } public hash. Code() { // requerido !!! return product. ID. hash. Code(); } public equals(Object prod) { // requerido !!! return ((Account. PK)prod). product. ID. equals(product. ID); } }
El Bean Product. Bean (1) import java. sql. *; public abstract class Productt. Bean implements Entity. Bean { Entity. Context ctx; public public abstract abstract public public. . void void String get. Name(); void set. Name(String name); String get. Description(); void set. Description(String desc); double get. Base. Price(); void set. Base. Price(double price); String get. Product. ID(); void set. Product. ID(String id); ejb. Activate() {} ejb. Pasivate() {} ejb. Remove() {} ejb. Load() {} ejb. Store() {}
El Bean Product. Bean (2). . . public void set. Entity. Context(Entity. Context ctx) { this. ctx = ctx; } public void unset. Entity. Context() {this. ctx = null; } public void ejb. Post. Create(String id, String name String desc, double price) {} public String Create(String id, String name String desc, double price) { set. Product. ID(id); set. Name(name); set. Description(desc); set. Base. Price(price); return id; //sorry esta en el libro } }
El Deployment descriptor es bastante grande, claro <!DOCTIPE ejb-jar PUBLIC. . . <ejb-jar> <enterprise-beans> <entity> <ejb-name>Product</ejb-name> <home>Product. Home</home> <remote>Product</remote> <ejb-class>Product. Bean</ejb-class> <persistence-type>Container</persistence-type> <primary-key-class>Product. PK</ primary-key-class > <reentrant>false</reentrant> <cmp-version>2. x</cmp-version> <abstract-schema-name>Product. Bean</abstract-schema-name> <cmp-field> <field-name>product. ID</field-name> </cmp-field> <field-name>name</field-name> </cmp-field> <field-name>description</field-name> </cmp-field> <field-name>base. Price</field-name> </cmp-field>
El Deployment descriptor es bastante grande, claro <query> <query-method> <method-name>find. By. Name</method-name> <method-params> <method-param>java. lang. String</method-param> <method-params> <query-method> <ejb-sql> <![CDATA[SELECT OBJECT (a) FROM Produc. Bean AS a WHERE name = ? 1> </ejb-sql> </query> <query-method> <method-name>find. Expensive. Products</method-name> <method-params> <method-param>double</method-param> <method-params> <query-method> <ejb-sql> <![CDATA[SELECT OBJECT (a) FROM Produc. Bean AS a WHERE base. Price > ? 1> </ejb-sql> </query> </entity> </enterprise-beans>
El Deployment descriptor es bastante grande, claro <assembly-descriptor>. . para transacciones. . . </assembly-descriptor>l </ejb-jar>
- Slides: 53