CMP Entity Beans y MySql

0
29670

CMP Entity Bean con MySql

Como comentamos en el anteriortutorial, la persistencia de un Entity Bean
puede ser gestionada por el contenedor.

En este tutorial vamos a ver los pequeños cambios que debemos realizar sobre
nuestro EJB, del mismo modo que os vamos a enseñar el truquillo para poder usar
la implementación de referencia de J2EE de Sun (J2EE RI) para usar MySql como
base de datos.

Como podemos suponer, pocas cosas deben cambiar… aunque hay algunas
sutilizas.

Lo que es realmente importante, es la definición del despliegue

 

Definición de interfaz Remoto

El único cambio, que además tiene mucho sentido, es la eliminación de la
definición del metodo setId.

Digo que tiene sentido porque cambiar la clave primaria normalmente requiere de otras precauciones.

package ejbfacturas;

/**
 *
 * Interfaz remoto a nuestro EJB de Facturas
 *
 * @author  Roberto Canales
 */
import java.rmi.*;
import javax.ejb.*;
import facturascomun.*;
import java.util.*;

public interface iFacturaItemCMP extends EJBObject
{
    public String getConcepto() throws java.rmi.RemoteException;
    public void setConcepto(String sConcepto) throws java.rmi.RemoteException;
    public String getFecha() throws java.rmi.RemoteException;
    public void setFecha(String sFecha) throws java.rmi.RemoteException;
    public String getDireccion() throws java.rmi.RemoteException;
    public void setDireccion(String sDireccion) throws java.rmi.RemoteException ;
    public String getTitular() throws java.rmi.RemoteException;
    public void setTitular(String sTitular) throws java.rmi.RemoteException;
    public String getCif() throws java.rmi.RemoteException;
    public void setCif(String sCif) throws java.rmi.RemoteException;
    public String getId() throws java.rmi.RemoteException;
    //public void setId(String iId) throws RemoteException, EJBException;
    public double getCantidad() throws java.rmi.RemoteException;
    public void setCantidad(double dCantidad) throws java.rmi.RemoteException;
}    

 

Definición del Interfaz Home

La definicón del interfaz Home, en este caso cambia en el tipo de retorno
del metodo findByPrimaryKey

package ejbfacturas;
/**
 *
 * @author  Roberto Canales
 */

import java.rmi.*;
import javax.ejb.*;
import java.io.*;
import java.util.*;

import facturascomun.*;

/**
 * Interfaz Home para definir los méodos de creación de nuestro EJB
 *
 */
public interface iFacturaItemHomeCMP extends EJBHome
{
    // ver las diferencias entre las declaraciones del Home y del Bean
    public iFacturaItemCMP create(Factura pFactura) throws CreateException, RemoteException;
    public iFacturaItemCMP findByPrimaryKey(String pParam) throws FinderException, RemoteException;
}

 

Implementación del Bean

Hay que realizar una definición de métodos abstractos

    public
abstract String getConcepto();
    public abstract void setConcepto(String sConcepto);
    public abstract String getFecha();
    public abstract void setFecha(String sFecha);
    public abstract String getDireccion();
    public abstract void setDireccion(String sDireccion);
    public abstract String getTitular();
    public abstract void setTitular(String sTitular);
    public abstract String getCif() ;
    public abstract void setCif(String sCif);
    public abstract String getId();
    public abstract void setId(String iId);
    public abstract double getCantidad();
    public abstract void setCantidad(double dCantidad);

Para asignar los valores del Bean, debemos invocar a los metodos, en el
ejbCreate

Por último, lo único que queda por hacer en el código, es borrar el
código que gestiona la persistencia.

package ejbfacturas;

/**
 * @author Roberto Canales
 */

import java.rmi.*;
import javax.ejb.*;
import java.sql.*;
import javax.sql.*;
import java.util.*;

import facturascomun.*;


public abstract class iFacturaItemBeanCMP implements EntityBean
{
    private void depura(String cadena)
    {
        System.out.println("EJB iFacturaItemBeanCMP: " + cadena);
    }


    private EntityContext context = null;

    /**
     * Metodo destinado a construir nuestro objeto
     *
     * Debe retornar la clave primaria del objeto creado
     */
    public String ejbCreate(Factura pFactura) throws CreateException
    {
        if (pFactura == null)
        {
            throw new CreateException("El Objeto retornado es nulo");
        }

        // asignamos las propiedades a los miembros de nuestra clase
        this.setId(pFactura.getId());  // clave primaria de nuestra factura
        this.setTitular(pFactura.getTitular());
        this.setConcepto(pFactura.getConcepto());
        this.setCif(pFactura.getCif());
        this.setDireccion(pFactura.getDireccion());
        this.setFecha(pFactura.getFecha());
        this.setCantidad(pFactura.getCandidad());

        return null;  // en un CMP se retorna NULL
    }

    /**
     * PosCreate del create construido
     */
    public void ejbPostCreate(Factura pFactura) throws CreateException
    {
        depura("Enviado post-create");
        // no es necesario código aunque si el metodo por haber escrito un create
    }


    /**
     * Metodo invocado por el contenedor para reactivar la instancia
     */
    public void ejbActivate() {
         depura("Se activa el EJB");
    }


    /**
     * Metodo invocado por el contenedor para desactivar la instancia
     */
    public void ejbPassivate() {
        depura("Se pasiva el EJB");
    }

    /**
     * Metodo invocado por el contenedor para borrar la instancia
     */
    public void ejbRemove()  throws RemoveException {
        depura("Borramos el EJB para id ");
     }

    /**
     * Metodo invocado por el contenedor para cargar de BBDD los datos de la instancia
     */
    public void ejbLoad() throws javax.ejb.EJBException, java.rmi.RemoteException {

        depura("Cargamos datos el EJB ");
    }

     /**
     * Metodo invocado por el contenedor para almacenar los datos cambiados
     */
    public void ejbStore() throws javax.ejb.EJBException, java.rmi.RemoteException {
        depura("Guardamos datos el EJB");
    }


     /**
     * Metodo invocado por el contenedor para pasarnos y desactivar el contexto
     */
    public void setEntityContext(javax.ejb.EntityContext entityContext) throws javax.ejb.EJBException, java.rmi.RemoteException {
            depura("Establecemos el contexto");
            this.context = entityContext; // si se nos olvida fallara el ejbActivate
    }


    public void unsetEntityContext() throws javax.ejb.EJBException, java.rmi.RemoteException {
            depura("Des-establecemos el contexto");
            context = null;
    }


    public abstract String getConcepto();
    public abstract void setConcepto(String sConcepto);
    public abstract String getFecha();
    public abstract void setFecha(String sFecha);
    public abstract String getDireccion();
    public abstract void setDireccion(String sDireccion);
    public abstract String getTitular();
    public abstract void setTitular(String sTitular);
    public abstract String getCif() ;
    public abstract void setCif(String sCif);
    public abstract String getId();
    public abstract void setId(String iId);
    public abstract double getCantidad();
    public abstract void setCantidad(double dCantidad);

}
    

Despliegue de la aplicación

Añadimos el EJB como hicimos con los anteriores

En la lengüeta de Entity asignamos un nombre para nuestras consultas EJB
(MICMP). Deberia ser un poco más estricto en la notación pero asi se ve mejor
…. 😉

Al pinchar el botón de Deployment Settings, aparece la configuración de la
base de datos.

Pulsamos Database Settings …

Asignamos el nombre JNDI de la base de datos (ver más abajo)

Pincharemos el botón de generar Default SQL

Y ya tenemos lista para funcionar nuestra aplicación. Ahora vamos a
configurar el entorno para poder usar MySql
(en Windows)

Registro de MySql

Pinchamos en la opción de configurar el servidor

Registramos un nuevo driver y nombre JNDI para la base de datos que queremos
utilizar

Hay un problema al hacer esto…. y es que las consultas SQL que genera el
CMP entity Bean, tienen dobles comillas.

Esto hace que falle…. el truco esta en cambiar la configuración de MySql
añadiendo un parámetro sql_mode=ansi

Dependiendo del sistema, se hace de un modo y otro. Nosotros como tenemos
instalado MySql como un servicio en Windows, vamos a cambiar el fichero de
configuración .

Ojo con ponerlo donde esta especificado y no meter espacios entre medias (en
el fichero My.ini)

#This File was made using the WinMySQLAdmin 1.4 Tool
#03/06/2003 11:33:57

#Uncomment or Add only the keys that you know how works.
#Read the MySQL Manual for instructions

[mysqld]
sql_mode=ansi
basedir=C:/mysql
#bind-address=10.43.20.18
datadir=C:/mysql/data
#language=C:/mysql/share/your language directory
#slow query log#=
#tmpdir#=
#port=3306
#set-variable=key_buffer=16M
[WinMySQLadmin]
Server=C:/mysql/bin/mysqld-nt.exe
user=rcanales
    

Para que J2EE RI encuentre el driver JDBC de MySQL, hay que descargarselo de
internet … (podeis ver el tutorial dedicado a su instalación yprueba) y
modificar el fichero userconfig.bat

Debemos añadir el trayecto donde lo hemos instalado

REM
REM Copyright 2002 Sun Microsystems, Inc. All rights reserved.
REM SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
REM

rem J2EE_CLASSPATH is appended to the classpath referenced by the EJB server.
rem J2EE_CLASSPATH must include the location of the JDBC driver classes
rem (except for the Cloudscape driver shipped with this release).
rem Each directory is delimited by a semicolon.
rem
set J2EE_CLASSPATH=C:\java\mysql-connector-java-3.0.7-stable\mysql-connector-java-3.0.7-stable-bin.jar
rem
rem JAVA_HOME refers to the directory where the Java(tm) 2 SDK
rem Standard Edition software is installed.
rem
rem set JAVA_HOME=
rem

    

Si ahora ejecutamos un código para probar nuestro EJB CMP…. hemos
cambiado  en EJB de sesión …..

     public boolean insertaNuevaFactura(Factura pFactura)
    {

        depura("Comenzamos la insercion de elementos CMP");

        try
        {
            Context contexto = new InitialContext();
            depura("Hemos creado el contexto y vamos a buscar objeto CMP");

            iFacturaItemHomeCMP miHome = null;

            Object objetoGenerico = contexto.lookup("java:comp/env/ejb/entidadfacturacmp");

            depura("La clase original es " + objetoGenerico.getClass().getName());
            miHome = (iFacturaItemHomeCMP) PortableRemoteObject.narrow(objetoGenerico,iFacturaItemHomeCMP.class);

            iFacturaItemCMP miFactura = miHome.create( pFactura);

            miFactura = miHome.findByPrimaryKey("22");
            depura("Vemos si se recupera " + miFactura.getId());

            depura("La operacion ha finalizado");
        }
        catch(Exception e)
        {
            depura("Error al probar ejb de entidad: " + e.getMessage());
        }

        return true;
    }
    

Y tambien un servlet

            contexto = getInitialContext();
            Object objetoGenerico = contexto.lookup("java:comp/env/ejb/gestorfacturas");
            miHome = (iFacturasHome)PortableRemoteObject.narrow(objetoGenerico,iFacturasHome.class);

            iFacturas ejbGestorFacturas = miHome.create();
            depura(out,"Número de facturas en BBDD = " + ejbGestorFacturas.recuperaNumeroFacturas());

            depura(out,"Vamos a insertar un nuevo elemento con EJB CMP");
            ejbGestorFacturas.insertaNuevaFactura(new Factura("73","AdictosAlTrabajo","Consultoria Tecnologica","54332112s", "Calle del Olivo", "28/10/2003", 5644.21));
            ejbGestorFacturas.insertaNuevaFactura(new Factura("22","AdictosAlTrabajo2","Consultoria Tecnologica2","54332112s2", "Calle del Olivo2", "28/12/2003", 5543.21));
            depura(out,"La operacion se ejecuto satisfactoriamente");

    

Si consultamos la BBDD, veremos que se ha creado la tabla e
insertados los elementos.

Podeis descargar todo elcódigo aquí …

Ya hemos cubierto otra fase ….. ahora tengo otra pregunta

¿Podemos intercambiar en el código el EJB con la persistencia
controlada por el Bean y por el contenedor?

Sobre
el Autor ..

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad