sábado, 6 de noviembre de 2010

Creación de una relacion uno - uno unidireccional

Para este ejemplo vamos a utilizar mi post llamado Creacion de Unidad de Persistencia con MySQL en Netbeans.

Primero creamos un paquete llamado com.ejemplo.session, dentro de este paquete creamos un Session Bean del tipo Stateless con interface Remota llamado Utilitario, que lo usaremos para probar la entidad.


Luego creamos otro paquete llamado com.ejemplo.entidades.unouno.unidireccional, en el proyecto EJB
Dentro de ese paquete vamos a crear un Entity Class

Lo vamos a llamar DatosPersonales que tendrá una variable miembro llamada descripción del tipo String. Tambien creamos los respectivos getters y setters con lo cual el código nos queda de la siguiente manera:


package com.ejemplo.entidades.unouno.unidireccional;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class DatosPersonales implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String descripcion;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getDescripcion() {
return descripcion;
}

public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}



@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
if (!(object instanceof DatosPersonales)) {
return false;
}
DatosPersonales other = (DatosPersonales) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}

@Override
public String toString() {
return "com.ejemplo.entidades.unouno.unidireccional.DatosPersonales[id=" + id + "]";
}
}

Después de esto creamos otro Entity Class llamado Cliente y le agregamos una variable miembro llamada nombre del tipo String. Tambien agregamos otra variable miembro llamada datosPersonales del tipo DatosPersonales, y sobre la definición de la variable la anotación:@OneToOne(cascade=CascadeType.ALL), esto para indicar la relación unidireccional con DatosPersonales. Tambien creamos los getters y setters de las variable miembro.

Con lo cual el código nos queda de la siguiente manera:


package com.ejemplo.entidades.unouno.unidireccional;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;

@Entity
public class Cliente implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String nombre;
@OneToOne(cascade=CascadeType.ALL)
private DatosPersonales datosPersonales;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public DatosPersonales getDatosPersonales() {
return datosPersonales;
}

public void setDatosPersonales(DatosPersonales datosPersonales) {
this.datosPersonales = datosPersonales;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}



@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
if (!(object instanceof Cliente)) {
return false;
}
Cliente other = (Cliente) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}

@Override
public String toString() {
return "com.ejemplo.entidades.unouno.unidireccional.Cliente[id=" + id + "]";
}

}


Hecho este código, vamos a la clase Utilitario de com.ejemplo.sesion.

Ahí hacemos una inyección del persistence Context y usamos un EntityManager para usar la entidad antes creada. Además creamos una funcion llamada relacionUnoUnoUniDireccional, que se encargará de insertar datos en cliente(No olvidemos que esta funcion tiene que estar tambien en la interface remota, podriamos usar Insert Code > Add Business Method en Netbeans).


Este objeto debe recibir un objeto del tipo DatosPersonales que tambien debe ser creado. Es decir:

package com.ejemplo.session;

import com.ejemplo.entidades.unouno.unidireccional.Cliente;
import com.ejemplo.entidades.unouno.unidireccional.DatosPersonales;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class Utilitario implements UtilitarioRemote {
@PersistenceContext EntityManager em;
public void relacionUnoUnoUniDireccional() {
DatosPersonales datosPersonales=new DatosPersonales();
datosPersonales.setDescripcion("Ejemplo");
datosPersonales.setId(1L);
Cliente cliente=new Cliente();
cliente.setId(1L);
cliente.setNombre("Santiago");
cliente.setDatosPersonales(datosPersonales);
em.persist(cliente);
}
}



Luego desde el Main del proyecto cliente, hacemos una inyección de EJB a UtilitarioRemote y llamamos al metodo relacionUnoUnoUniDireccional.

package relaciones;

import com.ejemplo.session.UtilitarioRemote;
import javax.ejb.EJB;

public class Main {

@EJB private static UtilitarioRemote utilitario;
public static void main(String[] args) {
utilitario.relacionUnoUnoUniDireccional();
}
}


Si hacemos una consulta en MySQL veremos que se crearon las tablas Cliente y DatosPersonales.
En cliente se inserto un registro, que guarda referencia a DatosPersonales
En Datos Personales veremos que se inserto un registro, pero sin referencia a Cliente, debido a que es una relación unidireccional


Creando una unidad de Persistencia en Netbeans

Creación de Unidad de Persistencia con MySQL en Netbeans

En este ejemplo estoy usando Netbeans 6.9, Ubuntu 10.04, Glassfish y MySQL Database
Para este ejemplo vamos a crear diferentes relaciones entre clases y por ende entre tablas en la base de datos.
Para esto creamos un proyecto empresarial llamado Relaciones:



Como primer paso vamos a crear una base de datos en mysql llamada DBRelaciones, para esto usamos el comando create database DBRelaciones desde la linea de comando de MySQL.

Una vez creada la base de datos, vamos a agregar la referencia de la libreria de MySQL a nuestro proyecto de Netbeans.

Luego creamos la unidad de persistencia desde Netbeans.
Damos boton derecho sobre el proyecto EJB y seleccionamos New/Other/persistence/Persistence Unit.

Le damos el nombre Relaciones-ejbPU, como proveedor de persistencia seleccionamos TopLink y en DataSource seleccionamos new DataSource y creamos un nuevo datasource a DBRelaciones,



una vez hecho esto seleccionamos como Table Generation Strategy Drop and Create y damos click en Finish

martes, 14 de septiembre de 2010

Creando un reporte con Pentaho

Pentaho Report Designer

Para este ejemplo estoy utilizando Ubuntu 10.04, MySQL Database y Pentaho Report Designer version 3.6.1


Para este ejemplo se presume que se tiene la base de datos de ejemplo de Pentaho instalada en MySQL, en caso de no tenerla, se deberá descargar el script de creacion de la base de datos usando subversion de la siguiente direccion svn://source.pentaho.org/svnroot/legacy/pentaho-data/trunk/mysql5/SampleDataDump_MySql.sql

Primeramente descargamos Pentaho Report Designer(prd-ce-3.6.1-stable.zip) de http://sourceforge.net/projects/pentaho/files/


y lo descomprimimos en algun lugar de nuestro equipo.

Luego ejecutamos report-designer.sh (en Windows report-designer.bat) y abrimos Pentaho Report Designer

Luego damos click sobre Report Wizard

Despues seleccionamos un Template o diseño para el reporte, en este caso usaremos Pentaho, luego damos click en Next

Luego damos click en Sample Query y damos click sobre el lápiz.

Seleccionamos SampleData(MySQL) y damos click en Sample Query de los Available Queries. Editamos el query de a SELECT * FROM PRODUCTS


Si damos click en Preview podremos ver la respectiva consulta:


Damos click en OK

Marcamos Simple Query y damos click en Next.

Vamos a realizar un reporte agrupado.
Para esto seleccionamos PRODUCTLINE Y PRODUCTVENDOR y damos click sobre la flecha que se encargará de agregarlos como Group Items. Luego seleccionamos PRODUCTNAME Y PRODUCTDESCRIPTION y los colocamos en la lista llamada Selected.


Si damos Click en Preview veremos como quedará nuestro reporte

Luego damos click en Next Aqui podemos seleccionar los diferentes campos y cambiar los títulos, anchos de las columnas, alignment,formatos de fechas, etc y con el botón Preview podemos ver como quedan dichos cambios.


Luego damos click en Finish.

Si damos click sobre el ojo del lado izquierdo podremos ver el Preview de nuestro reporte

Si queremos salir del Preview podemos dar click sobre el lápiz

Ahora vamos a crear el mismo reporte sin el asistente.

Para esto damos click sobre el boton del nuevo o seleccionamos File/New

Luego creamos un nuevo Dataset para esto vamos por Data/Add Data Source/JDBC. Seleccionamos SampleData(MySQL) y damos click sobre el simbolo "+"
Colocamos un nombre al Query y con el Query "SELECT * FROM PRODUCTS" y damos click en OK

Luego arrastramos PRODUCTNAME Y PRODUCTDESCRIPTION de Consulta1 a la sección de details

Hecho esto damos click sobre la pestaña Structure y buscamos Groups, damos click son el botón derecho sobre Groups y seleccionamos Add Group. De los Available Fields seleccionamos PRODUCTLINE Y PRODUCTVENDOR y los pasamos a la lista de Selected Fields y damos click en OK


Finalmente seleccionamos la pestaña Data y arrastramos PRODUCTLINE Y PRODUCTVENDOR a la sección de Group Header y hacemos un Preview del reporte, con lo que tenemos

Creando Portlet para Liferay en Netbeans

En este ejemplo, vamos a crear un portlet con Netbeans, Portal Pack, Liferay, JSTL y Liferay.

Para este ejemplo estoy usando Netbeans 6.9, Ubuntu 10.04, Liferay 6.0.5





Primero descargamos la version Liferay Community Edition de http://www.liferay.com/downloads/liferay-portal/overview con Bundled Tomcat y damos click en GO

Instalando los plugins en Netbeans
Primeramente descargamos Portal Pack(portal-pack-plugin-3_0_4_all.zip) de http://contrib.netbeans.org/portalpack/pp30/download304.html
Hecho esto descomprimimos el archivo y abrimos Netbeans
Ahora tenemos que instalar el plugin, para esto seleccionamos Tools/Plugins y luego la pestaña Downloaded y damos click en Add Plugins. Buscamos el directorio en el cual descomprimimos Portal Pack y seleccionamos todos los plugins y damos click en OK. Luego damos click en install y dejamos listo el ambiente en Netbeans para trabajar con portlets



Creando nuestro proyecto Portlet
Primero creamos un nuevo proyecto web en Netbeans, para mi caso lo voy a llamar PortletEjemplo.


En la pantalla de selección del servidor damos click sobre add y agregamos el servidor llamado Liferay Portal Server 5.1-x/5.2.x/6.x y damos click en Next
Entonces configuramos el servidor de la siguiente manera(dependiendo de la ruta en donde se encuentra instalado Liferay y su Tomcat embebido), damos click en Next


y dejamos la siguiente pantalla de la siguiente manera

Entonces regresamos a la pantalla de creación de la aplicación , damos click sobre Next

y marcamos Portlet Support. damos click sobre Create Portlet y configuramos los paquetes, títulos, descripciones, etc de nuestro Portlet y damos click en Finish.


Ahora tenemos que dar soporte JSTL a nuestra APP, para esto damos click con el botón derecho y seleccionamos Properties luego Libraries y damos click sobre Add Library y agregamos JSTL 1.1. Damos click en ok

Si abrimos PortletEjemplo.java que se encuentra dentro del paquete com.ejemplo.portlet1 y en el método doView(...) agregamos atributos al request. Dejándolo de la siguiente manera:

public void doView(RenderRequest request,RenderResponse response) throws PortletException,IOException {
response.setContentType("text/html");
request.setAttribute("mensaje1", "Este es el contenido del mensaje1"); request.setAttribute("mensaje2", "Este es el contenido del mensaje2"); request.setAttribute("mensaje3", "Este es el contenido del mensaje3"); PortletRequestDispatcher dispatcher =
getPortletContext().getRequestDispatcher("/WEB-INF/jsp/PortletEjemplo_view.jsp");
dispatcher.include(request, response);
}

Para que el ejemplo sea de una manera gráfica más agradable, vamos a usar Jquery 1.8.4.
El cual lo descargamos de http://jqueryui.com/download


Descomprimimos el zip y copiamos los directorios js y css dentro del directorio "Web Pages" de nuestro proyecto.


Entonces abrimos Web Pages/WEB-INF/jsp/PortletEjemplo_view.jsp y creamos un llamada al taglib de jstl para poder llamar a los scripts y estilos de JQuery, también usamos EL para mostrar la información que colocamos en el request. Con lo cual la página jsp, nos queda de la siguiente manera:
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<link type="text/css" href="<c:url value="/css/ui-lightness/jquery-ui-1.8.4.custom.css"/>" rel="stylesheet" />
<script type="text/javascript" src='<c:url value="/js/jquery-1.4.2.min.js"/>'></script>
<script type="text/javascript" src="<c:url value="/js/jquery-ui-1.8.4.custom.min.js"/>"></script>

<script type="text/javascript">
$(function(){
$("#accordion").accordion({ header: "h3" });
});
</script>


<h2 class="demoHeaders">Accordion</h2>
<div id="accordion">
<div>
<h3><a href="#">Opción 1</a></h3>
<div>${mensaje1}</div>
</div>
<div>
<h3><a href="#">Opción 2</a></h3>
<div>${mensaje2}</div>
</div>
<div>
<h3><a href="#">Opción 3</a></h3>
<div>${mensaje3}</div>
</div>
</div>


Haciendo Deploy del proyecto en Netbeans
Cuando ya terminemos esto, seleccionamos el proyecto y lo ejecutamos.

Como verlo desde Liferay
Luego de ejecutar se abre el navegador de Internet(http://localhost:8080//) y damos click en Sign In, como usuario colocamos test@liferay.com y como clave test y luego click en Sign In. Ahi pasamos el mouse por Add y damos click en More.



Buscamos User Portlets y damos click en Add de Portlet Ejemplo. Con lo cual se nos agrega el nuevo Portlet a nuestro GUI





Nota: PortletEjemplo cannot be cast to javax.portlet.Portlet, se recomienda eliminar el contenido de los directorios temp y work del Tomcat de Liferay

jueves, 2 de septiembre de 2010

Eclipse Helios & Apache Click

Para este ejemplo estoy usando Ubuntu 10.04, Eclipse Helios, Tomcat V6 y Apache Click versió 2.2.0

Primeramente vamos a descargar click-2.2.0.zip de http://click.apache.org/docs/downloads.html



Descomprimimos el archivo en algun lugar directorio de nuestro computador.

Hecho esto abrimos Eclipse y creamos un nuevo Dynamic Web Project, para mi caso lo voy a llamar ProyectoClick.

Ahora, voy a configurar el proyecto para que tenga soporte para Click. Para esto doy click con el boton derecho del mouse sobre el proyecto y selecciono la opción Import y luego nuevamente la opción Import.
Luego selecciono General/File System y doy click en Next.

Ahi doy click en Browse y busco el directorio en el cual se extrajo Apache Click 2.2.0 y selecciono el directorio dist.
Luego marco click-2.2.0.jar y click-extras-2.2.0.jar.
En Into folder doy click sobre browse y elijo la ruta ProyectoClick/WebContent/WEB-INF/lib, ya que estas librerias deberán guardarse en el directorio lib de WEB-INF.



Finalmente doy click en Finish

Con esto tengo listo el ambiente para usar click en Eclipse.

Nota: Tenemos que tener claro un concepto en Click y es la correspondencia entre las clases y las páginas.Por ejemplo una pagina llamada pagina1.htm, tiene correspondecia con la clase Pagina1Page. una página llamada informacion, tiene correspondencia con la clase InformacionPage.

El primer paso para poder usar Click es indicarle al aplicativo Web que tiene que usar las clases de Click, para esto abro web.xml y agrego las siguientes definiciones del Servlet de Click, con lo que web.xml, nos quedará como:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>ProyectoClick</display-name>
<servlet>
<servlet-name>ClickServlet</servlet-name>
<servlet-class>org.apache.click.ClickServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ClickServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>inicio.htm</welcome-file>
</welcome-file-list>
</web-app>


Realizado este cambio tenemos que crear click.xml en el directorio WEB-INF. En este archivo colocamos diferente información de configuración para Click, por ejemplo el paquete en el cual se encuentran las clases que corresponderán con las páginas. En este ejemplo colocaremos las clases en el paquete com.ejemplo.paginas Con lo cual click.xml queda de la siguiente manera:
<?xml version="1.0" encoding="UTF-8"?>
<click-app>
<pages package="com.ejemplo.paginas"/>
</click-app>


El siguiente paso es crear una clase. Para este ejemplo vamos a crear una clase llamada InicioPage en el paquete com.ejemplo.paginas con el siguiente código:
package com.ejemplo.paginas;
import org.apache.click.Page;
public class InicioPage extends Page {
protected String mensaje="Esta es una prueba de Apache Click";
public InicioPage() {
addModel("message", mensaje);
}
}

Luego de esto tenemos que crear una página llamada inicio.htm en WebContent. Esta página tiene el siguiente código:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Apache Click</title>
</head>
<body>
<p>$mensaje</p>
</body>
</html>

Hecho esto, ejecutamos nuestro proyeco y tenemos la siguiente salida:



Ahora compliquemos un poco más la cosas. Vamos a crear un formulario, para esto vamos a crear:
informacion.htm junto con InformacionPage.java
mostrarInformacion.html junto con MostrarInformacionPage.java


InformacionPage.java

package com.ejemplo.paginas;

import org.apache.click.Page;
import org.apache.click.control.Form;
import org.apache.click.control.Submit;
import org.apache.click.control.TextField;


public class InformacionPage extends Page{
public Form formulario = new Form();
private TextField txtNombre;
private TextField txtTelefono;
private TextField txtEmail;

public InformacionPage() {
formulario.setLabelsPosition(Form.POSITION_TOP);
txtNombre = new TextField("Cual es tu nombre?:");
txtTelefono=new TextField("Cual es tu telefono?:");
txtEmail=new TextField("Cual es tu email?:");
formulario.add(txtNombre);
formulario.add(txtTelefono);
formulario.add(txtEmail);
formulario.add(new Submit("Submit", this, "funcionSubmit"));
}

public boolean funcionSubmit(){
MostrarInformacionPage pagina2 = (MostrarInformacionPage)getContext().createPage("/mostrarInformacion.htm");
pagina2.setNombre(txtNombre.getValue());
pagina2.setTelefono(txtTelefono.getValue());
pagina2.setEmail(txtEmail.getValue());
setForward(pagina2);
return false;
}
}





MostrarInformacionPage.java
package com.ejemplo.paginas;

import org.apache.click.Page;

public class MostrarInformacionPage extends Page {
private String nombre;
private String telefono;
private String email;

public void setNombre(String nombre) {
this.nombre = nombre;
}
public void setTelefono(String telefono) {
this.telefono = telefono;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public void onInit()
{
super.onInit();
if (nombre != null && telefono!=null && email!=null)
{
addModel("nombre",nombre);
addModel("telefono",telefono);
addModel("email",email);
}
}
}



Informacion.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Apache Click</title>
</head>
<body>
$formulario
</body>
</html>


mostrarInformacion.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Apache Click</title>
</head>
<body>
<b></>Tu nombre es:</b>$nombre<br/>
<b></>Tu telefono es:</b>$telefono<br/>
<b></>Tu email es:</b>$email<br/>
</body>
</html>

miércoles, 1 de septiembre de 2010

Spring Framework, Hibernate y Maven en 4 pasos

Spring Framework, Hibernate y Maven en 4 pasos

SPRING FRAMEWORK

Para este ejemplo estoy usando Ubuntu 10.04, Maven y una base de datos MySQL con el esquema test.

Creamos un schema en la base de datos con un tabla:
create database ejemplo;
use ejemplo;
create table producto(
id int not null,
nombre varchar(20),
valor double,
PRIMARY KEY(id));


https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=7089-jta-1.0.1B-mr-class-oth-JSpec@CDS-CDS_Developer

mvn install:install-file -Dfile=jta-1_0_1B-classes.zip -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -Dpackaging=jar

Paso 1) Creación y Configuración de proyecto de Maven

Creacion de proyecto Maven
mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.ejemplo -DartifactId=proyecto1

Luego abrimos pom.xml y agregamos dependencias, repositories y plugins a nuestro archivo de configuracion de maven de tal manera que quede de la siguiente manera

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ejemplo</groupId>
<artifactId>proyecto1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>proyecto1</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>JBoss repository</id>
<url>http://repository.jboss.com/maven2/</url>
</repository>
<repository>
<id>Java.Net</id>
<url>http://download.java.net/maven/2/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>hibernate</groupId>
<artifactId>hibernate3</artifactId>
<version>3.2.3.GA</version>
</dependency>
<dependency>
<groupId>hibernate-annotations</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.0.GA</version>
</dependency>
<dependency>
<groupId>hibernate-commons-annotations</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.0.0.GA</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
</project>

Luego ejecutamos mvn clean install



mkdir -p src/main/java/com/ejemplo/negocio/model
mkdir -p src/main/java/com/ejemplo/negocio/util
mkdir -p src/main/java/com/ejemplo/negocio/dao
mkdir -p src/main/java/com/ejemplo/negocio/bo
mkdir -p src/main/java/com/ejemplo/negocio/dao/impl
mkdir -p src/main/java/com/ejemplo/negocio/bo/impl
mkdir -p src/main/java/resources

Paso 2)Archivos de configuración del proyecto
En este paso vamos a crear:
- Archivo de propiedades
- DataSource.xml
- Hibernate.xml
- BeanLocations.xml


En el directorio resources de main del proyecto de maven, vamos a crear un archivo de propiedades llamado database.properties, el cual tendrá informacion relacionada a la base de datos a la cual nos vamos a conectar:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ejemplo
jdbc.username=root
jdbc.password=root

Luego creamos un archivo llamado DataSource.xml, el cual tendra información para la fuente de datos de la aplicación, en base al archivo de propiedades antes creado:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>database.properties</value>
</property>
</bean>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>

</beans>


Una vez hecho esto tenemos que crear el archivo Hibernate.xml, que usará la información de DataSource para la configuración de hibernate.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.ejemplo.negocio.model.Producto</value>
</list>
</property>
</bean>
</beans>


Finalmente, tenemos que crear el archivo BeanLocations.xml para indicarle a Spring como se va a conectar a la base de datos y en que paquetes estan los recursos que usará la aplicación:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<!-- Database Configuration -->
<import resource="DataSource.xml"/>
<import resource="Hibernate.xml"/>

<!-- Auto scan the components -->
<context:component-scan
base-package="com.ejemplo.negocio" />

</beans>

Paso 3) Creacion de clases.
En este paso vamos a crear:
1.Mapeo a la base de datos.
2.Data Access Objects
3.Business Objects


Primeramente debemos crear una clase padre, encargada de utilizar la anotación Autowired.
Creamos el archivo SoporteHibernateDao en la ruta src/main/java/com/ejemplo/negocio/util

package com.ejemplo.negocio.util;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class SoporteHibernateDao extends HibernateDaoSupport{
@Autowired
public void metodoSoporte(SessionFactory sessionFactory){
setSessionFactory(sessionFactory);
}
}

Luego de hecho esto, vamos a crear una clase utilitaria que nos permita recuperar los beans del contexto de hibernate, esta clase se llama SpringContext y va dentro del archivo SpringContext.java que se encontrará guardado en la ruta:src/main/java/com/ejemplo/negocio/util
package com.ejemplo.negocio.util;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringContext{
private static ApplicationContext contexto;
private static SpringContext instancia;
private final static String ARCHIVO_CONF = "BeanLocations.xml";
public static SpringContext getInstance() {
if (null == instancia) {
instancia = new SpringContext();
contexto = new ClassPathXmlApplicationContext(ARCHIVO_CONF);
}
return instancia;
}

public Object getBean(String nombreBean) {
return contexto.getBean(nombreBean);
}
}


Dentro del directorio src/main/java/com/ejemplo/negocio/model, creamos un archivo con la clase llamada Producto.Esta clase se encuentra mapeada por medio de anotaciones a la tabla producto de la Base de Datos, es decir:

package com.ejmplo.negocio.model;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

@Entity
@Table(name = "producto")
@NamedQueries({
@NamedQuery(name = "Producto.findAll", query = "SELECT p FROM Producto p"),
@NamedQuery(name = "Producto.findById", query = "SELECT p FROM Producto p WHERE p.id = :id"),
@NamedQuery(name = "Producto.findByNombre", query = "SELECT p FROM Producto p WHERE p.nombre = :nombre"),
@NamedQuery(name = "Producto.findByValor", query = "SELECT p FROM Producto p WHERE p.valor = :valor")})
public class Producto implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Column(name = "nombre")
private String nombre;
@Column(name = "valor")
private Double valor;

public Producto() {
}

public Producto(Integer id, String nombre, Double valor){
this.id=id;
this.nombre=nombre;
this.valor=valor;
}

public Producto(Integer id) {
this.id = id;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public Double getValor() {
return valor;
}

public void setValor(Double valor) {
this.valor = valor;
}
}

Una vez hecho esto, debemos crear la interface DAO, para esto creamos el archivo ProductoDao.java en src/main/java/com/ejemplo/negocio/dao, con el siguiente código:
package com.ejemplo.negocio.dao;
import com.ejemplo.negocio.model.Producto;
import java.util.List;

public interface ProductoDao{
void save(Producto producto);
void delete(Producto producto);
Producto findById(Integer id);
List<Producto> findAll();
}


Luego de creado esto, debemos implementar esta interface. Para eso creamos el archivo llamado ProductoDaoImpl.java, en la ruta src/main/java/com/ejemplo/negocio/dao/impl, con el siguiente código:
package com.ejemplo.negocio.dao.impl;
import com.ejemplo.negocio.dao.ProductoDao;
import com.ejemplo.negocio.model.Producto;
import com.ejemplo.negocio.util.SoporteHibernateDao;
import java.util.List;
import org.springframework.stereotype.Repository;

@Repository("productoDao")
public class ProductoDaoImpl extends SoporteHibernateDao implements ProductoDao{
public void save(Producto producto){
getHibernateTemplate().save(producto);
}
public void delete(Producto producto){
getHibernateTemplate().delete(producto);
}
public Producto findById(Integer id){
String[] nombreParametros={"id"};
Object[] parametros={id};
return (Producto)(getHibernateTemplate().findByNamedQueryAndNamedParam("Producto.findById",nombreParametros,parametros).get(0));
}
public List<Producto> findAll(){
return (List<Producto>)getHibernateTemplate().findByNamedQuery("Producto.findAll");
}
}

Hecho, esto tenemos que crear los Business Objects que serán los usados por nuestro cliente:
Primero, creamos el archivo ProductoBo.java en la ruta:src/main/java/com/ejemplo/negocio/bo

package com.ejemplo.negocio.bo;
import com.ejemplo.negocio.model.Producto;
import java.util.List;

public interface ProductoBo{
void guardar(Producto producto);
void eliminar(Producto producto);
Producto recuperarPorId(Integer id);
List<Producto> recuperarTodos();
}


Luego implementamos esta interface en el archivo ProductoBoImpl que se encuentra en la ruta:src/main/java/com/ejemplo/negocio/dao/impl

package com.ejemplo.negocio.bo.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import com.ejemplo.negocio.bo.ProductoBo;
import com.ejemplo.negocio.dao.ProductoDao;
import com.ejemplo.negocio.model.Producto;

@Service("productoBo")
public class ProductoBoImpl implements ProductoBo{
@Autowired
ProductoDao productoDao;

public void setProductoDao(ProductoDao productoDao){
this.productoDao=productoDao;
}

public void guardar(Producto producto){
productoDao.save(producto);
}
public void eliminar(Producto producto){
productoDao.delete(producto);
}
public Producto recuperarPorId(Integer id){
return productoDao.findById(id);
}
public List<Producto> recuperarTodos(){
return productoDao.findAll();
}
}

Paso 4) Creación de cliente

Una vez creadas estas clases, podemos crear un test. Para este ejemplo voy a usar el archivo App.java que se encuentra dentro de:src/test/java/com/ejemplo

package com.ejemplo;

import com.ejemplo.negocio.bo.ProductoBo;
import com.ejemplo.negocio.model.Producto;
import com.ejemplo.negocio.util.SpringContext;

import org.apache.log4j.Logger;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{

private static Logger logger = Logger.getLogger(AppTest.class);

public AppTest( String testName )
{
super( testName );
}

public static Test suite()
{
return new TestSuite( AppTest.class );
}

public void testApp()
{
SpringContext contexto = SpringContext.getInstance();
ProductoBo productoBo=(ProductoBo)contexto.getBean("productoBo");
Producto p=new Producto(1,"jabon",13.00);
productoBo.guardar(p);
Producto p1=productoBo.recuperarPorId(1);
System.out.println("Recuperacion individual:"+p1.getNombre());
for(Producto producto:productoBo.recuperarTodos()){
System.out.println("Recuperacion Lista:"+producto.getNombre());
}
productoBo.eliminar(p);

}
}


Finalmente ejecuto mvn clean:install desde una consola de comandos, tengo la siguiente salida:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.ejemplo.AppTest
Hibernate: insert into producto (nombre, valor, id) values (?, ?, ?)
Hibernate: select producto0_.id as id0_, producto0_.nombre as nombre0_, producto0_.valor as valor0_ from producto producto0_ where producto0_.id=?
Recuperacion individual:jabon
Hibernate: select producto0_.id as id0_, producto0_.nombre as nombre0_, producto0_.valor as valor0_ from producto producto0_
Recuperacion Lista:jabon
Hibernate: select producto_.id, producto_.nombre as nombre0_, producto_.valor as valor0_ from producto producto_ where producto_.id=?
Hibernate: delete from producto where id=?
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.67 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: /home/santiago/proyecto1/target/proyecto1-1.0-SNAPSHOT.jar
[INFO] [install:install {execution: default-install}]
[INFO] Installing /home/santiago/proyecto1/target/proyecto1-1.0-SNAPSHOT.jar to /home/santiago/.m2/repository/com/ejemplo/proyecto1/1.0-SNAPSHOT/proyecto1-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9 seconds
[INFO] Finished at: Wed Sep 01 16:45:40 ECT 2010
[INFO] Final Memory: 21M/154M
[INFO] ------------------------------------------------------------------------

martes, 17 de agosto de 2010

Stateless VS Stateful

En este ejemplo voy a demostrar la diferencia entre Stateful Beans y Stateless Beans.
Para este ejemplo estoy usando Ubuntu version 10.04, Netbeans 3.0 y Glassfish V3.
Primeramente creamos una aplicacion Java EE, desde Netbeans

Para mi caso la voy a llamar SessionProject

Seleccionamos Glassfish como servidor y marcamos la casilla de creacion de un cliente para probar nuestra aplicación.



Una vez hecho esto, creamos un EJB Session Bean llamado StatefulBean, Este bean es Remoto de tipo Stateful en el paquete com.ejb.stateful

Ahora tenemos crear los métodos, para esto usamos Netbeans y dentro de StatefulBean damos click con el botón derecho seleccionamos InsertCode y luego AddBusinessMethod y creamos un método llamado incremetar, que devuelve un Integer



Una vez acabado esto nos quedará el siguiente código:
Para la Interface

package com.ejb.stateful;

import javax.ejb.Remote;

@Remote
public interface StatefulBeanRemote {

Integer incrementar();

}

ParaStatefulBean:

package com.ejb.stateful;

import javax.ejb.Stateful;

@Stateful
public class StatefulBean implements StatefulBeanRemote {
private Integer valor=0;
public Integer incrementar() {
return ++valor;
}

}


Ahora vamos a crear el Stateless.
Una vez hecho esto, creamos un EJB Session Bean llamado StatelessBean, Este bean es Remoto de tipo Stateless en el paquete com.ejb.stateless

Ahora tenemos crear los métodos, para esto usamos Netbeans y dentro de StatefulBean damos click con el botón derecho seleccionamos InsertCode y luego AddBusinessMethod y creamos un método llamado incremetar, que devuelve un Integer


Una vez acabado esto nos quedará el siguiente código:
Para la Interface


package com.ejb.stateless;

import javax.ejb.Remote;

@Remote
public interface StatelessBeanRemote {

Integer incrementar();
}



Para StatelessBean

package com.ejb.stateless;

import javax.ejb.Stateless;

@Stateless
public class StatelessBean implements StatelessBeanRemote {
private Integer valor=0;
public Integer incrementar() {
return ++valor;
}
}


Hecho esto, vamos a cambiar las propiedades del proyecto para ejecutar el cliente.Para esto damos botón derecho sobre el proyecto principal(SessionProject) y seleccionamos properties. Luego seleccionamos Run y en el Client Module seleccionamos SessionProject-app-client.


Una vez configurado, abrimos la clase main de SessionProject-app-client
damos boton derecho sobre el método main y seleccionamos InsertCode y luego "Call Enterprise Bean". Luego de esto seleccionamos SessionProject-ejb y en Reference Name colocamos statefulbean1. Los mismos pasos seguimos para statefulbean2, statelessbean1,statelessbean2



Con esto se nos genera el siguiente código:
@EJB(name = "statefulbean1")
private static StatefulBeanRemote statefulbean1;
@EJB(name = "statefulbean2")
private static StatefulBeanRemote statefulbean2;
@EJB(name = "statelessbean1")
private static StatelessBeanRemote statelessbean1;
@EJB(name = "statelessbean2")
private static StatelessBeanRemote statelessbean2;


Luego agregamos el siguiente código en el método main:
System.err.println("Variable Stateful1");
System.err.println(statefulbean1.incrementar());
System.err.println(statefulbean1.incrementar());
System.err.println(statefulbean1.incrementar());

System.err.println("Variable Stateful2");
System.err.println(statefulbean2.incrementar());
System.err.println(statefulbean2.incrementar());
System.err.println(statefulbean2.incrementar());

System.err.println("Variable Stateless1");
System.err.println(statelessbean1.incrementar());
System.err.println(statelessbean1.incrementar());
System.err.println(statelessbean1.incrementar());

System.err.println("Variable Stateless2");
System.err.println(statelessbean2.incrementar());
System.err.println(statelessbean2.incrementar());
System.err.println(statelessbean2.incrementar());


Con lo que el código final nos quedará como:
package sessionproject;

import com.ejb.stateful.StatefulBean;
import com.ejb.stateful.StatefulBeanRemote;
import com.ejb.stateless.StatelessBean;
import com.ejb.stateless.StatelessBeanRemote;
import javax.ejb.EJB;

public class Main {


@EJB(name = "statefulbean1")
private static StatefulBeanRemote statefulbean1;
@EJB(name = "statefulbean2")
private static StatefulBeanRemote statefulbean2;
@EJB(name = "statelessbean1")
private static StatelessBeanRemote statelessbean1;
@EJB(name = "statelessbean2")
private static StatelessBeanRemote statelessbean2;

public static void main(String[] args) {
System.err.println("Variable Stateful1");
System.err.println(statefulbean1.incrementar());
System.err.println(statefulbean1.incrementar());
System.err.println(statefulbean1.incrementar());

System.err.println("Variable Stateful2");
System.err.println(statefulbean2.incrementar());
System.err.println(statefulbean2.incrementar());
System.err.println(statefulbean2.incrementar());

System.err.println("Variable Stateless1");
System.err.println(statelessbean1.incrementar());
System.err.println(statelessbean1.incrementar());
System.err.println(statelessbean1.incrementar());

System.err.println("Variable Stateless2");
System.err.println(statelessbean2.incrementar());
System.err.println(statelessbean2.incrementar());
System.err.println(statelessbean2.incrementar());
}
}


Si ejecutamos el proyecto principal(SessionProject)
En la consola tenemos la siguiente salida:

Variable Stateful1
1

2
3
Variable Stateful2
1
2
3
Variable Stateless1
1
2
3
Variable Stateless2
4
5
6

La idea es que los cambios a stateless afectará a todas las instancias creadas de stateless. Mientras que en stateful, las instancias son independientes y no se ven afectadas.