martes, 14 de junio de 2011

Java Persistence Query Language

Para este ejemplo estoy utilizando Netbeans 6.9, Ubuntu 10.04, Glassfish 3.0 y Derby DB.
En este ejemplo voy a ejemplificar el funcionamiento de EJB en un Enterprise Project. Para esto vamos a crear un Enterprise Project llamado ConsultasEJBQL.





Luego de eso en el proyecto EJB vamos a crear una unidad de persistencia. La llamaremos puEJBQL, EclipseLink será el proveedor de persistencia y apuntará al datasource jdbc/sample de Derby y como estrategia de generación de las tablas, seleccionamos None.

Hecho esto, vamos a crear beans de entidad por medio de la opción: "Entity Classes from Database"
Seleccionamos todas las tablas, damos click sobre Next.




Luego colocamos un paquete, en este caso es: com.ejemplo.ejb.entity y damos click sobre Next.

En la caja de selección de Collection Type, seleccionamos java.util.List y damos click en Finish.



Una vez creados los Entity Beans vamos a crear un Session Bean del tipo Stateless, con interface remoto, llamado Utilitario en el paquete com.ejemplo.ejb.session

A continuación muesto ciertas consultas EJBQL, definidas en Utilitario.

package com.ejemplo.ejb.session;

import com.ejemplo.ejb.entity.Customer;
import com.ejemplo.ejb.entity.Manufacturer;
import com.ejemplo.ejb.entity.Product;
import com.ejemplo.ejb.entity.ProductCode;
import java.util.List;
import java.util.Vector;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class Utilitario implements UtilitarioRemote {

@PersistenceContext
EntityManager em;

@Override
public void getAllCustomers() {
String consulta1 = "select obj from Customer obj";
System.err.println("____CONSULTA CUSTOMER____");
Query query = em.createQuery(consulta1);
for (Customer customer : (List) query.getResultList()) {
System.out.println(customer.getName());
}
}

@Override
public void getCustomerByName(String parametro) {
String consulta2 = "select obj from Customer obj where obj.city=:ciudad";
System.err.println("____CONSULTA CUSTOMER PARAMETRIZADA____");
Query query = em.createQuery(consulta2);
query.setParameter("ciudad", parametro);
for (Customer customer : (List) query.getResultList()) {
System.out.println(customer.getName());
}
}

@Override
public void consultaMaximoResultados() {
String consulta1 = "select obj from Customer obj";
System.err.println("____CONSULTA MAXIMA RESULTADOS____");
Query query = em.createQuery(consulta1);
query.setMaxResults(5);
for (Customer customer : (List) query.getResultList()) {
System.out.println(customer.getName());
}
}

@Override
public void consultaUnica() {
String resultadoUnico = "select obj from Customer obj where obj.customerId=:id";
System.err.println("____CONSULTA UNICA____");
Integer parametro = 1;
Query query = em.createQuery(resultadoUnico);
query.setParameter("id", parametro);
Customer customer = (Customer) query.getSingleResult();
System.out.println(customer.getName());
}

@Override
public void consultarNamedQuery() {
String consultaNamedQuery = "Product.findAll";
System.err.println("____CONSULTA NAMED QUERY____");
Query query = em.createNamedQuery(consultaNamedQuery);
for (Product product : (List) query.getResultList()) {
System.out.println(product.getDescription());
}
}

@Override
public void consultarNamedQueryAddress() {
String consultaNamedQueryDireccion = "Customer.findByAddressline1";
System.err.println("____CONSULTA NAMED QUERY DIRECCION____");
Query query = em.createNamedQuery(consultaNamedQueryDireccion);
query.setParameter("addressline1", "9754 Main Street");
for (Customer customer : (List) query.getResultList()) {
System.out.println(customer.getName());
}
}

@Override
public void consultarNativeQuery() {
String consultaNativeQuery = "Select * from Manufacturer";
System.err.println("____CONSULTA NAMED QUERY____");
Query query = em.createNativeQuery(consultaNativeQuery, Manufacturer.class);
for (Manufacturer fabricante : (List) query.getResultList()) {
System.out.println(fabricante.getName());
}
}

@Override
public void consultarNativeQueryLista() {
String consultaNativeQueryList = "Select name,state,city from Manufacturer";
System.err.println("____CONSULTA NATIVE QUERY____");
Query query = em.createNativeQuery(consultaNativeQueryList);
List resultados = (List) query.getResultList();
for (int i = 0; i < resultados.size(); i++) {
//System.out.println((Vector) resultados.get(i));//Usado para TopLink
System.out.println(java.util.Arrays.toString((Object[]) resultados.get(i)));//Usado para EclipseLink
}
}

@Override
public void consultarPosicional() {
String consultaPosicional = "select obj from Manufacturer obj where obj.city=?1";
System.err.println("____CONSULTAR POSICIONAL____");
String parametro1 = "San Jose";
Query query = em.createQuery(consultaPosicional);
query.setParameter(1, parametro1);
for (Manufacturer manufacturer : (List) query.getResultList()) {
System.out.println(manufacturer.getName());
}
}

@Override
public void consultaGrupo() {
String consultaGrupo = "select pc.prodCode from ProductCode pc GROUP BY pc.prodCode";
System.err.println("____CONSULTA GRUPO____");
Query query = em.createQuery(consultaGrupo);
List resultados = (List) query.getResultList();
for (int i = 0; i < resultados.size(); i++) {
System.out.println((String) resultados.get(i));
}
}

@Override
public void actualizar() {
String update = "UPDATE MicroMarket mm SET mm.areaLength=mm.areaWidth";
Query query = em.createQuery(update);
query.executeUpdate();
}

@Override
public void eliminar() {
Manufacturer m = new Manufacturer();
m.setManufacturerId(777);
m.setName("ejemplo");
m.setAddressline1("Amazonas");
m.setAddressline2("NNUU");
m.setCity("Quito");
m.setState("Pi");
m.setZip("123");
m.setPhone("123456789");
m.setFax("987654321");
m.setEmail("ejemplo@gmail.com");
m.setRep("cualquiera");
em.persist(m);
String delete = "DELETE FROM Manufacturer c WHERE c.name ='ejemplo'";
Query query = em.createQuery(delete);
query.executeUpdate();
}

@Override
public void consultaGroupBy() {
String consultaGroupBy = "SELECT p.productCode.prodCode,AVG(p.purchaseCost) FROM Product p GROUP BY p.productCode.prodCode ORDER BY p.productCode.prodCode ASC";
System.err.println("____CONSULTA GROUP BY____");
Query query = em.createQuery(consultaGroupBy);
List resultados = (List) query.getResultList();
for (int i = 0; i < resultados.size(); i++) {
System.out.println(((Object[]) resultados.get(i))[0] + "," + ((Object[]) resultados.get(i))[1]);
}
}

@Override
public void consultaPrecios() {
String consultarValoresEntre = "SELECT p FROM Product p WHERE p.purchaseCost<:maximo AND p.purchaseCost>:minimo";
System.err.println("____CONSULTA VALOR ENTRE____");
Query query = em.createQuery(consultarValoresEntre);
query.setParameter("maximo", new Double(40));
query.setParameter("minimo", new Double(10));
for (Product p : (List) query.getResultList()) {
System.out.println(p.getDescription());
}
}

@Override
public void consultaPrecios2() {
String consultarValoresEntre2 = "SELECT p FROM Product p WHERE p.purchaseCost BETWEEN :minimo AND :maximo";
System.err.println("____CONSULTA VALOR ENTRE 2____");
Query query = em.createQuery(consultarValoresEntre2);
query.setParameter("maximo", new Double(40));
query.setParameter("minimo", new Double(10));
for (Product p : (List) query.getResultList()) {
System.out.println(p.getDescription());
}
}

@Override
public void consultaLike() {
String consultarLike = "SELECT p FROM Product p WHERE p.description LIKE 'Lea%'";
System.err.println("____CONSULTA LIKE____");
Query query = em.createQuery(consultarLike);
for (Product p : (List) query.getResultList()) {
System.out.println(p.getDescription());
}
}

@Override
public void consultaJoin() {
String consultaJoin1 = "select pc FROM ProductCode pc join pc.productList p WHERE p.purchaseCost>10000";
System.err.println("____CONSULTA JOIN____");
Query query = em.createQuery(consultaJoin1);
for (ProductCode pc : (List) query.getResultList()) {
System.out.println(pc.getDescription());
}
}

@Override
public void consultarJoin2() {
String consultarJoin2 = "select p from Product p LEFT join p.productCode HW";
System.err.println("____CONSULTA JOIN____");
Query query = em.createQuery(consultarJoin2);
for (Product p : (List) query.getResultList()) {
System.out.println(p.getDescription());
}
}

@Override
public void consultarJoin3() {
String consultarJoin3 = "SELECT Object(pc) FROM ProductCode pc, IN (pc.productList) pl where pc.prodCode='SW'";
System.err.println("____CONSULTA JOIN____");
Query query = em.createQuery(consultarJoin3);
for (ProductCode pc : (List) query.getResultList()) {
System.out.println(pc.getDescription());
}
}

@Override
public void consultarJoin4() {
String consultarJoin4 = "select pc FROM ProductCode pc join pc.productList p WHERE p.quantityOnHand>50";
System.err.println("____CONSULTA JOIN____");
Query query = em.createQuery(consultarJoin4);
for (ProductCode pc : (List) query.getResultList()) {
System.out.println(pc.getDescription());
}
}

@Override
public void consultarJoin5() {
String consultarJoin5 = "SELECT DISTINCT pc FROM ProductCode pc, IN(pc.productList) l WHERE l.manufacturer.name = 'Acer'";
System.err.println("____CONSULTA JOIN____");
Query query = em.createQuery(consultarJoin5);
for (ProductCode pc : (List) query.getResultList()) {
System.out.println(pc.getDescription());
}
}

@Override
public void consultarJoin6() {
String consultarJoin6 = "SELECT pc from ProductCode pc LEFT JOIN pc.productList o WHERE pc.prodCode='SW'";
System.err.println("____CONSULTA JOIN____");
Query query = em.createQuery(consultarJoin6);
for (ProductCode pc : (List) query.getResultList()) {
System.out.println(pc.getDescription());
}
}

@Override
public void consultaFuncion() {
String consultaFuncionRaiz = "select SQRT(p.purchaseCost) from Product p";
System.err.println("____CONSULTA FUNCION SQRT____");
Query query = em.createQuery(consultaFuncionRaiz);
List resultados = (List) query.getResultList();
for (int i = 0; i < resultados.size(); i++) {
System.out.println((Double) resultados.get(i));
}
}
}




Esta es la interface remota de Utilitario:

package com.ejemplo.ejb.session;

import javax.ejb.Remote;

@Remote
public interface UtilitarioRemote {
public void getAllCustomers();

public void getCustomerByName(String ciudad);

public void consultaMaximoResultados();

public void consultaUnica();

public void consultarNamedQuery();

public void consultarNamedQueryAddress();

public void consultarNativeQuery();

public void consultarNativeQueryLista();

public void consultarPosicional();

public void consultaJoin();

public void consultaGrupo();

public void consultaFuncion();

public void actualizar();

public void eliminar();

public void consultarJoin2();

public void consultarJoin3();

public void consultaGroupBy();

public void consultaPrecios();

public void consultaPrecios2();

public void consultaLike();

public void consultarJoin4();

public void consultarJoin5();

public void consultarJoin6();

}


y este es el código de la clase Main:

package consultaejbql;

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

public class Main {

@EJB private static UtilitarioRemote utilitario;
public static void main(String[] args) {
utilitario.getAllCustomers();
utilitario.getCustomerByName("New York");
utilitario.consultaMaximoResultados();
utilitario.consultaUnica();
utilitario.consultarNamedQuery();
utilitario.consultarNamedQueryAddress();
utilitario.consultarNativeQuery();
utilitario.consultarNativeQueryLista();
utilitario.consultarPosicional();
utilitario.consultaJoin();
utilitario.consultaFuncion();
utilitario.consultaGrupo();
utilitario.actualizar();
utilitario.eliminar();
utilitario.consultarJoin3();
utilitario.consultaPrecios();
utilitario.consultaPrecios2();
utilitario.consultaLike();
utilitario.consultaGroupBy();
}
}

y la salida es:
SEVERE: ____CONSULTA CUSTOMER____
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
INFO: EclipseLink, version: Eclipse Persistence Services - 2.0.1.v20100213-r6600
INFO: file:/home/santiago/NetBeansProjects/ConsultaEJBQL/dist/gfdeploy/ConsultaEJBQL/ConsultaEJBQL-ejb_jar/_puEJBQL login successful
INFO: JumboCom
INFO: Livermore Enterprises
INFO: Oak Computers
INFO: Nano Apple
INFO: HostProCom
INFO: CentralComp
INFO: Golden Valley Computers
INFO: ejemplo
INFO: West Valley Inc.
INFO: Ford Motor Co
INFO: Big Car Parts
INFO: New Media Productions
INFO: Yankee Computer Repair
SEVERE: ____CONSULTA CUSTOMER PARAMETRIZADA____
INFO: New Media Productions
INFO: Yankee Computer Repair
SEVERE: ____CONSULTA MAXIMA RESULTADOS____
INFO: JumboCom
INFO: Livermore Enterprises
INFO: Oak Computers
INFO: Nano Apple
INFO: HostProCom
SEVERE: ____CONSULTA UNICA____
INFO: JumboCom
SEVERE: ____CONSULTA NAMED QUERY____
INFO: Identity Server
INFO: Accounting Application
INFO: 1Ghz Sun Blade Computer
INFO: 10Gb Ram
INFO: Sound Card
INFO: Printer Cable
INFO: 24 inch Digital Monitor
INFO: 104-Key Keyboard
INFO: Directory Server
INFO: 512X IDE DVD-ROM
INFO: Learn Solaris 10
INFO: Network Cable
INFO: 300Mhz Pentium Computer
INFO: Learn NetBeans
INFO: Corporate Expense Survey
INFO: Sun Studio C++
INFO: Client Server Testing
INFO: Learn Java in 1/2 hour
INFO: Writing Web Service Applications
INFO: Jax WS Application Development Environment
INFO: Java EE 6 Application Development Environment
INFO: Java Application Development Environment
INFO: NetBeans Development Environment
INFO: Solaris x86 Computer
INFO: Ultra Spacr 999Mhz Computer
INFO: 686 7Ghz Computer
INFO: A1 900 watts Speakers
INFO: Mini Computer Speakers
INFO: Computer Tool Kit
INFO: Flat screen Monitor
SEVERE: ____CONSULTA NAMED QUERY DIRECCION____
INFO: Livermore Enterprises
SEVERE: ____CONSULTA NAMED QUERY____
INFO: Google
INFO: Sun MicroSystems
INFO: Acer
INFO: Matrox
INFO: 3Com
INFO: CBX Cables
INFO: Sony
INFO: Getaway
INFO: SoftClip
INFO: Toshiba
INFO: Sams Publishing
INFO: Computer Cables & More
INFO: BMC
INFO: Rico Enterprises
INFO: Dobs Computer Products
INFO: Zetsoft
INFO: Hitachi
INFO: World Savings
INFO: Wells Fargo
INFO: Bank Of America
INFO: Google
INFO: Google
INFO: Google
INFO: Sun MicroSystems
INFO: Sun MicroSystems
INFO: Sun MicroSystems
INFO: Sun MicroSystems
INFO: Sun MicroSystems
INFO: Sun MicroSystems
INFO: Sun MicroSystems
INFO: fabricante1
INFO: fabricante1
INFO: fabricante1
INFO: fabricante1
INFO: Ejemplo Clase
INFO: fabricante1
SEVERE: ____CONSULTA NATIVE QUERY____
INFO: [Google, CA, Mountain View]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [Acer, CA, San Jose]
INFO: [Matrox, CA, Novato]
INFO: [3Com, CA, El Cerrito]
INFO: [CBX Cables, IN, Indianapolis]
INFO: [Sony, CA, San Francisco]
INFO: [Getaway, CA, Santa Clara]
INFO: [SoftClip, MA, Boston]
INFO: [Toshiba, CA, Van Nuys]
INFO: [Sams Publishing, MA, Reading]
INFO: [Computer Cables & More, MI, Dearborn]
INFO: [BMC, CA, Pleasanton]
INFO: [Rico Enterprises, NY, New York]
INFO: [Dobs Computer Products, NM, Albuqerque]
INFO: [Zetsoft, AZ, Tombstone]
INFO: [Hitachi, CA, San Mateo]
INFO: [World Savings, CA, Oakland]
INFO: [Wells Fargo, CA, San Francisco]
INFO: [Bank Of America, CA, San Francisco]
INFO: [Google, CA, Mountain View]
INFO: [Google, CA, Mountain View]
INFO: [Google, CA, Mountain View]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [Sun MicroSystems, CA, Santa Clara]
INFO: [fabricante1, null, null]
INFO: [fabricante1, null, null]
INFO: [fabricante1, null, null]
INFO: [fabricante1, null, null]
INFO: [Ejemplo Clase, null, null]
INFO: [fabricante1, null, null]
SEVERE: ____CONSULTAR POSICIONAL____
INFO: Acer
SEVERE: ____CONSULTA JOIN____
INFO: Software
SEVERE: ____CONSULTA FUNCION SQRT____
INFO: 33.090784215548595
INFO: 107.24266874709897
INFO: 45.78198335590104
INFO: 7.742738533619742
INFO: 6.320601237224193
INFO: 3.997499218261337
INFO: 24.392621835300936
INFO: 3.3090784215548594
INFO: 7.067531393633848
INFO: 8.363611660042569
INFO: 5.475399528801528
INFO: 5.094114250780011
INFO: 44.73197961190629
INFO: 5.472659317004851
INFO: 8.660254037844387
INFO: 24.412087170088512
INFO: 4.466542286825459
INFO: 4.3531597719357835
INFO: 4.998999899979995
INFO: 14.489651479590528
INFO: 16.122964987867462
INFO: 16.430155203162265
INFO: 14.830711378757258
INFO: 37.429266623859995
INFO: 28.284094470214175
INFO: 24.412087170088512
INFO: 8.36540495134575
INFO: 7.067531393633848
INFO: 6.078651166171653
INFO: 14.140367746278736
SEVERE: ____CONSULTA GRUPO____
INFO: BK
INFO: CB
INFO: FW
INFO: HW
INFO: MS
INFO: SW
SEVERE: ____CONSULTA JOIN____
INFO: Software
INFO: Software
INFO: Software
INFO: Software
INFO: Software
INFO: Software
INFO: Software
INFO: Software
SEVERE: ____CONSULTA VALOR ENTRE____
INFO: Sound Card
INFO: Printer Cable
INFO: 104-Key Keyboard
INFO: Learn Solaris 10
INFO: Network Cable
INFO: Learn NetBeans
INFO: Client Server Testing
INFO: Learn Java in 1/2 hour
INFO: Writing Web Service Applications
INFO: Computer Tool Kit
SEVERE: ____CONSULTA VALOR ENTRE 2____
INFO: Sound Card
INFO: Printer Cable
INFO: 104-Key Keyboard
INFO: Learn Solaris 10
INFO: Network Cable
INFO: Learn NetBeans
INFO: Client Server Testing
INFO: Learn Java in 1/2 hour
INFO: Writing Web Service Applications
INFO: Computer Tool Kit
SEVERE: ____CONSULTA LIKE____
INFO: Learn Solaris 10
INFO: Learn NetBeans
INFO: Learn Java in 1/2 hour
SEVERE: ____CONSULTA GROUP BY____
INFO: BK,24.764
INFO: CB,20.965
INFO: FW,49.95
INFO: HW,717.2372
INFO: MS,55.975
INFO: SW,1775.2112

lunes, 13 de junio de 2011

Métodos Callback para EJBs de Entidad

Para este ejemplo estoy usando Netbeans 6.9, Ubuntu 10.04, Glassfish V3 y Derby

Primeramente vamos a crear un Enterprise Project llamado CallBackEntity.


Creamos una unidad de persistencia que la llamaremos como:pucb. Seleccionamos TopLink como la libreria de persistencia. Como Conexión a la Base de Datos seleccionamos la conexión a la base de datos de sample de Derby y como la estrategia de generación de las tablas seleccionamos None.


Luego de esto, tenemos que crear un Entity Bean en base a las tablas del schema de la base de datos.Para lograr esto creamos un EntityBean usando "Entity Classes from DataBase". Al abrirse la ventana seleccionamos y pasamos al lado derecho la tabla Manufacturer.

Luego damos click en Next y colocamos el paquete com.ejemplo.entity.

Damos click en Next y la siguiente ventana en la opción collection list, seleccionamos java.util.List y damos click en Finish.


Hecho esto se nos genera el Entity Bean llamado Manufacturer.

En esta clase vamos a agregar las anotaciones relacionadas a las operaciones con la base de datos.

Tambien cambiamos el método toString(), para poder imprimir las variable miembro.

Con lo que el código nos queda como:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.ejemplo.entity;

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.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import javax.persistence.Table;

/**
*
* @author santiago
*/
@Entity
@Table(name = "MANUFACTURER")
@NamedQueries({
@NamedQuery(name = "Manufacturer.findAll", query = "SELECT m FROM Manufacturer m"),
@NamedQuery(name = "Manufacturer.findByManufacturerId", query = "SELECT m FROM Manufacturer m WHERE m.manufacturerId = :manufacturerId"),
@NamedQuery(name = "Manufacturer.findByName", query = "SELECT m FROM Manufacturer m WHERE m.name = :name"),
@NamedQuery(name = "Manufacturer.findByAddressline1", query = "SELECT m FROM Manufacturer m WHERE m.addressline1 = :addressline1"),
@NamedQuery(name = "Manufacturer.findByAddressline2", query = "SELECT m FROM Manufacturer m WHERE m.addressline2 = :addressline2"),
@NamedQuery(name = "Manufacturer.findByCity", query = "SELECT m FROM Manufacturer m WHERE m.city = :city"),
@NamedQuery(name = "Manufacturer.findByState", query = "SELECT m FROM Manufacturer m WHERE m.state = :state"),
@NamedQuery(name = "Manufacturer.findByZip", query = "SELECT m FROM Manufacturer m WHERE m.zip = :zip"),
@NamedQuery(name = "Manufacturer.findByPhone", query = "SELECT m FROM Manufacturer m WHERE m.phone = :phone"),
@NamedQuery(name = "Manufacturer.findByFax", query = "SELECT m FROM Manufacturer m WHERE m.fax = :fax"),
@NamedQuery(name = "Manufacturer.findByEmail", query = "SELECT m FROM Manufacturer m WHERE m.email = :email"),
@NamedQuery(name = "Manufacturer.findByRep", query = "SELECT m FROM Manufacturer m WHERE m.rep = :rep")})
public class Manufacturer implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "MANUFACTURER_ID")
private Integer manufacturerId;
@Column(name = "NAME")
private String name;
@Column(name = "ADDRESSLINE1")
private String addressline1;
@Column(name = "ADDRESSLINE2")
private String addressline2;
@Column(name = "CITY")
private String city;
@Column(name = "STATE")
private String state;
@Column(name = "ZIP")
private String zip;
@Column(name = "PHONE")
private String phone;
@Column(name = "FAX")
private String fax;
@Column(name = "EMAIL")
private String email;
@Column(name = "REP")
private String rep;

public Manufacturer() {
}

public Manufacturer(Integer manufacturerId) {
this.manufacturerId = manufacturerId;
}

public Integer getManufacturerId() {
return manufacturerId;
}

public void setManufacturerId(Integer manufacturerId) {
this.manufacturerId = manufacturerId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddressline1() {
return addressline1;
}

public void setAddressline1(String addressline1) {
this.addressline1 = addressline1;
}

public String getAddressline2() {
return addressline2;
}

public void setAddressline2(String addressline2) {
this.addressline2 = addressline2;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public String getZip() {
return zip;
}

public void setZip(String zip) {
this.zip = zip;
}

public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

public String getFax() {
return fax;
}

public void setFax(String fax) {
this.fax = fax;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getRep() {
return rep;
}

public void setRep(String rep) {
this.rep = rep;
}

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

@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Manufacturer)) {
return false;
}
Manufacturer other = (Manufacturer) object;
if ((this.manufacturerId == null && other.manufacturerId != null) || (this.manufacturerId != null && !this.manufacturerId.equals(other.manufacturerId))) {
return false;
}
return true;
}

@Override
public String toString() {
return " Manufacturer id:" + this.manufacturerId
+ " Name :" + this.name
+ " Address Line 1:" + this.addressline1
+ " Address Line 2:" + this.addressline2
+ " City:" + this.city
+ " State:" + this.state
+ " Zip:" + this.zip
+ " Phone:" + this.phone
+ " Fax:" + this.fax
+ " Email:" + this.email
+ " Rep:" + this.rep;
}

@PrePersist
public void antesGuardar() {
System.out.println("Antes de Guardar");
}

@PostPersist
public void luegoGuardar() {
System.out.println("Luego de Guardar");
}

@PreRemove
public void antesEliminar() {
System.out.println("Antes de Eliminar");
}

@PostRemove
public void luegoEliminar() {
System.out.println("Luego de Eliminar");
}

@PreUpdate
public void antesActualizar() {
System.out.println("Antes de Actualizar");
}

@PostUpdate
public void luegoActualizar() {
System.out.println("Luego de Actualizar");
}

@PostLoad
public void alCargar() {
System.out.println("Cargando el objeto en el contexto");
}
}

Después de esto creamos un EJB de Session Stateless con interface remota, llamado Utilitario, dentro de com.ejemplo.session. Que tenga funciones que se encarguen de llamar a rutinas para guardar, eliminar y actualizar la tabla Manufacturer en la base de datos.
Es decir:
package com.ejemplo.session;

import com.ejemplo.entity.Manufacturer;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class Utilitario implements UtilitarioRemote {

@PersistenceContext EntityManager em;

public void guardar(Manufacturer m) {
em.persist(m);
}

public void eliminar(Manufacturer m) {
em.remove(em.find(com.ejemplo.entity.Manufacturer.class, m.getManufacturerId()));
}

public void actualizar(Manufacturer m) {
em.merge(m);
}
}

Luego, hacemos clean and build sobre el Enterprise Project

Finalmente hacemos una inyección de EJB en la clase Main donde crearemos,actualizaremos y eliminaremos objetos del tipo Manufacturer. De esta manera:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package callbackentity;

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

public class Main {
@EJB private static UtilitarioRemote util;
public static void main(String[] args) {
//Creando uno nuevo
Manufacturer m = new Manufacturer();
m.setManufacturerId(987);
m.setName("Santiago");
m.setAddressline1("Amazonas");
m.setAddressline2("NNUU");
m.setCity("Quito");
m.setState("Pi");
m.setZip("123");
m.setPhone("123456789");
m.setFax("987654321");
m.setEmail("ejemplo@gmail.com");
m.setRep("cualquiera");
util.guardar(m);
System.out.println(m.toString());
//Actualizando
m.setRep("cualquier12345");
util.actualizar(m);
System.out.println(m.toString());
//Eliminando
util.eliminar(m);
}
}

En el log de la aplicación tenemos:

y en el log de Glassfish tenemos:

Métodos CallBack para Session Beans

Para este ejemplo estoy usando Netbeans 6.9, Ubuntu 10.04 y Glassfish V3

Los métodos callback son similares a usar triggers de una base de datos, es decir son ejecutados cuando se ejecuta alguna acción sobre el objeto, estas acciones pueden ser instanciación(constructor), eliminación(destructor), desactivar(stateful beans) o activar(stateful beans)

Para ejemplificar lo que hacen estos métodos, vamos a crear un Enterprise Project llamado CallbackSesion.


Luego de esto, vamos a crear un EJB de session del tipo stateless con interface remota llamado EJBStateless en el paquete com.ejemplo.stateless.


Tambien vamos a crear un session bean del tipo Stateful con interface remota llamado EJBStateful en el paquete com.ejemplo.stateful.


Para EJBStateless agregamos las funciones creacionObjeto y eliminarObjeto, con el siguiente código:

package com.ejemplo.stateless;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Remove;
import javax.ejb.Stateless;

@Stateless
public class EJBStateless implements EJBStatelessRemote {

@PostConstruct
public void creacionObjeto() {
System.err.println("Se esta creando el objeto Stateless");
}

public void mostrarMensaje() {
System.out.println("Este es un EJB de session de tipo Stateless");
}

@Remove
public void eliminarObjeto() {
System.out.println("..........Se esta ejecutando funcion para eliminar el objeto Stateless");
}

@PreDestroy
public void mensajePreDestroy() {
System.err.println(".......Etapa de Pre Destroy Stateless");
}
}




Para EJBStateful agregamos las funciones creacionObjeto y eliminarObjeto, con el siguiente código:
package com.ejemplo.stateful;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Remove;
import javax.ejb.Stateful;

@Stateful
public class EJBStateful implements EJBStatefulRemote {

@PostConstruct
public void creacionObjeto() {
System.err.println("Se esta creando el objeto Stateful");
}


public void mostrarMensaje() {
System.out.println("Este es un EJB de session de tipo Stateful");
}

@Remove
public void eliminarObjeto() {
System.out.println("Se esta ejecutando funcion para eliminar el objeto Stateful");
}

@PreDestroy
public void mensajePreDestroy() {
System.err.println("Etapa de Pre Destroy Stateful");
}

}
Tenemos que destacar que en el código antes escrito se usan las anotaciones @PostConstruct y @PreDestroy, estas sirven para señalar que funciones se ejecutarán. También la anotación @Remove, que es la que nos permitirá indicar la función que será la encargada de eliminar el objeto.


Hecho esto, vamos a realizar una inyección de EJB en la clase Main, de nuestro cliente.
Es decir:

package callbacksesion;

import com.ejemplo.stateful.EJBStatefulRemote;
import com.ejemplo.stateless.EJBStatelessRemote;
import javax.ejb.EJB;


public class Main {
@EJB private static EJBStatefulRemote stateful;
@EJB private static EJBStatelessRemote stateless;

public static void main(String[] args) {
stateless.mostrarMensaje();
stateful.mostrarMensaje();
stateful.eliminarObjeto();
stateless.eliminarObjeto();
}

}
Con lo que tenemos la siguiente salida:


y al detener el servidor:

Timer Services

Para este ejemplo estoy usando Netbeans 6.9, Ubuntu 10.04 y Glassfish V3.
Un timer es una rutina que llamada cada cierto tiempo por el servidor de aplicaciones, es similar a un cron job.
Para probar como funcionan los timers vamos a crear un Enterprise Applicaction llamado TimerProject.
Luego creamos un EJB de Session, Stateles y con interface remota, en el paquete com.ejemplo Llamaremos a la clase Timer1

Después de esto agregamos una función llamada invocacion1(). Programaremos esta función para que se ejecute cada minuto.
Es decir:

package com.ejemplo;

import javax.ejb.Schedule;
import javax.ejb.Stateless;

@Stateless
public class Timer1 implements Timer1Remote {
@Schedule(minute="*",hour="*")
public void invocacion1() {
System.out.println("Esta es una invocación que se realiza cada minuto");
}
}

Luego hacemos click con el boton derecho sobre el EnterpriseProject y seleccionamos deploy.

Finalmente desde la pestaña de services levantamos el servidor


y esperamos un minuto para revisar el log del servidor:



Tenemos otra manera de ejecutar un timer y es por medio de la inyección de recursos.
Para este ejemplo voy a ejecutar un timer a los 1000 ms de iniciado el servidor y se ejecutará la función tarea() cada 20000 ms. Para eso debo crear la función llamada tarea():


Para eso voy a modificar la clase Timer1, de la siguiente manera:

package com.ejemplo;

import javax.annotation.Resource;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

@Stateless
public class Timer1 implements Timer1Remote {

int tiempoInicio=1000;
int tiempoRepeticion=20000;
String mensaje="Llamada a la rutina";
@Resource TimerService timerService;


@Schedule(minute="*",hour="*")
public void invocacion1() {
System.out.println("Esta es una invocación que se realiza cada x segundos");
}

public void crearTimer() {
System.out.println("Dentro del metodo crear Timer");
System.out.println("Cada "+tiempoRepeticion+" se ejecutará la función tarea");
Timer timer = timerService.createTimer(tiempoInicio,tiempoRepeticion,
mensaje);
}
@Timeout
public void tarea(Timer timer) {
System.out.println("Aqui se hará la respectiva codificación");
}

}


Al ejecutar tenemos la siguiente salida:

Métodos Callback de Interceptores

Para este ejemplo estoy usando Ubuntu 10.04, Netbeans 6.9 y Glassfish V3.
En un post anterior usamos Interceptores con métodos de negocio. Para este post vamos a usar metodos callback en interceptores.
Tenemos cuatro tipos de anotaciones callback:
- PostConstruct(Stateless, Stateful y MDB)
- PreDestroy(Stateless, Stateful y MDB)
- PostActivate(Stateful)
- PrePassivate(Stateful)



Primeramente creamos un Enterprise Project llamado CallbackInterceptors.

Luego creamos un EJB del tipo Stateless con interface remota llamado Utilitario, dentro del paquete com.ejemplo.



Ahi creamos una función llamada mostrarMensaje que imprima en pantalla un saludo:



package com.ejemplo;

import javax.ejb.Stateless;

@Stateless
public class Utilitario implements UtilitarioRemote {

public void mostrarMensaje() {
System.out.println("Saludos desde el EJB");
}
}


Luego de eso creamos una clase interceptora llamada: ClaseInterceptoraLifeCycle en el paquete: com.ejemplo.interceptores. La cual va a tener las funciones:
mensajePostConstruct(InvocationContext inv) con la anotación: @PostConstructque será llamada luego de ejecutarse la inyección de EJB y la función mensajePreDestroy(InvocationContext inv) con la anotación:@PreDestroy que será llamda luego de ser eleiminado el objeto.
Es decir:

package com.ejemplo.interceptores;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.interceptor.InvocationContext;

public class ClaseInterceptoraLifeCycle {

@PostConstruct
public void mensajePostConstruct(InvocationContext inv){
System.out.println("Test PostConstruct");
}


@PreDestroy
public void mensajePreDestroy(InvocationContext inv){
System.out.println("Test PreDestroy");
}
}

Hecho esto, tenemos que modificar la clase Stateless EJB, para que soporte el Interceptor creado, para eso agregamos la anotación:@Interceptors({
com.ejemplo.interceptores.ClaseInterceptoraLifeCycle.class
})
Con lo que el código nos queda como:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package com.ejemplo;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

/**
*
* @author santiago
*/
@Stateless
@Interceptors({
com.ejemplo.interceptores.ClaseInterceptoraLifeCycle.class
})
public class Utilitario implements UtilitarioRemote {

public void mostrarMensaje() {
System.out.println("Saludos desde el EJB");
}
}

Finalmente en la clase Main, hacemos la inyección de EJB a Utilitario


y obtenemos el siguiente resultado:



y si detenemos el servidor:


Usando Interceptores de Negocio(Business Interceptors)

Para este ejemplo estoy usando Ubuntu 10.04, Netbeans 6.9 y Glassfish V3

La idea de usar interceptores en una aplicación EJB es la misma que usar Filtros en un aplicación Web.
Para ilustrar el uso de interceptores vamos a crear un Projecto Empresarial en Netbeans.
Ahora creamos un Stateless Session Bean con una interface remota, en el paquete com.ejemplo.ejb. Llamaremos al EJB como Utilitario

Hecho esto vamos a crear un metodo llamado mostrarMensaje(), que tiene un parámetro del tipo String.





La clase EJB nos quedará de la siguiente manera:

package com.ejemplo;

import javax.ejb.Stateless;

@Stateless
public class Utilitario implements UtilitarioRemote {
public void mostrarMensaje(String cadena) {
System.out.println("El parametro ingresado es:"+cadena);
}
}

Luego de esto desde el cliente EJB hacemos una Inyección EJB y llamamos al EJB Utilitario
Con lo cual el código nos queda como:

package interceptoresnegocio;

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

public class Main {

@EJB private static UtilitarioRemote bean;
public static void main(String[] args) {
bean.mostrarMensaje("Esta es una prueba");
}

}

Luego ejecutamos el ejemplo y tenemos la siguiente salida:
INFO: El parametro ingresado es:Esta es una prueba


Hasta ahora nada de ciencia, pero en este momento vamos a cambiar el mensaje que se imprime

Primeramente, tenemos que crear un clase. Para esto damos boton derecho sobre el proyecto EJB y seleccionamos New Java Class.
Le damos el nombre de Interceptor1 y le creamos dentro del paquete:com.ejemplo.interceptores


La clase interceptora usa la anotación:@AroundInvoke y la clase InvocationContext, para obtener información de environment, por ejemplo: los métodos y los parámetros. Además siempre siempre debe devolver la función proceed de InvocationContext.
La clase interceptora, tendrá el siguiente código:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package com.ejemplo.interceptores;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

/**
*
* @author santiago
*/
public class Interceptor1 {
@AroundInvoke
public Object interceptorClase(InvocationContext inv) throws Exception {
long tiempoInicio = System.currentTimeMillis();
String nombreFuncion = "";
Object[] parametros = null;
try {
nombreFuncion = inv.getMethod().getName();
parametros = inv.getParameters();
return inv.proceed();
} finally {
long tiempo = tiempoInicio - System.currentTimeMillis();
System.out.println(inv.getMethod() + " La ejecución en la clase Interceptora1 de la función "
+ nombreFuncion + " tomó:" + tiempo + "milliseconds.");
System.out.println("Con los parametros:"
+ java.util.Arrays.toString(parametros));
}
}
}

Hecho esto vamos a usar la anotación @Interceptors en la clase EJB que implementa la interface remota.Con lo que la clase nos queda como:

package com.ejemplo;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
@Interceptors({
com.ejemplo.interceptores.Interceptor1.class
})
public class Utilitario implements UtilitarioRemote {

public void mostrarMensaje(String cadena) {
System.out.println("El parametro ingresado es:"+cadena);
}
}

Si ejecutamos la clase Main, veremos que en la consola nos sale la información del tiempo de ejecución de la clase



Ahora vamos a cambiar el valor del parámetro de la función mostrarMensaje por medio de un nuevo Interceptor.
Para esto creamos una clase que se llame InterceptorParametro de la misma manera que creamos la clase Interceptor1. Es decir:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.ejemplo.interceptores;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

/**
*
* @author santiago
*/
public class InterceptorParametro {

@AroundInvoke
public Object interceptorClase(InvocationContext inv) throws Exception {
try {
Object[] parametros = inv.getParameters();
parametros[0] = "Valor cambiado por el Interceptor";
inv.setParameters(parametros);
} finally {
return inv.proceed();
}
}
}

y agregamos el nuevo interceptor en la clase Utilitario, es decir:

package com.ejemplo;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
@Interceptors({
com.ejemplo.interceptores.Interceptor1.class,
com.ejemplo.interceptores.InterceptorParametro.class
})
public class Utilitario implements UtilitarioRemote {

public void mostrarMensaje(String cadena) {
System.err.println("El parametro ingresado es:"+cadena);
}
}

y ejecutamos la Enterprise Application:
y obtenemos la siguiente salida:
SEVERE: El parametro ingresado es:Valor cambiado por el Interceptor

sábado, 29 de enero de 2011

Como crear un datasource en Tomcat para una base de datos MySQL.

Para este ejemplo estoy usando Ubuntu 10.04, Tomcat 6 y tengo creada una base de datos en mysql, llamada db1, con permisos para el usuario “root”, con clave “root”

1.

Primeramente abrimos el archivo conf.xml de <CATALINA_HOME>/conf

2.

Luego agregamos las siguientes lineas dentro del contexto:

<Resource name="jdbc/conexionDB" auth="Container" type="javax.sql.DataSource"

maxActive="100" maxIdle="30" maxWait="10000"

username="root" password="root" driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/db1"/>


3.

Copiamos el driver de MySQL a: <CATALINA_HOME>/lib



4.

Creamos un nuevo proyecto web, dentro de webapps con la siguiente estructura:

webapps

----ejemplodb

----------conexion.jsp

----------WEB-INF

---------------lib

--------------------jstl.jar

---------------------standard.jar

----------web.xml


Nota: Para esta prueba descargamos las librerias jstl.jar y standard.jar para poder hacer pruebas con Tag Lib y SQL.


5.

Modificamos web.xml para que tenga la siguiente forma:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

version="2.4">

<description>Conexion MySQL</description>

<resource-ref>

<description>Conexion base de datos</description>

<res-ref-name>jdbc/conexionDB</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource-ref>

</web-app>


Nota: jdbc/conexionDB es el nombre que definimos en context.xml

5.

Creamos la pagina conexion.jsp, con el siguiente codigo:

<%@page contentType="text/html" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<sql:query var="rs" dataSource="jdbc/conexionDB">

SELECT name,salary FROM PROFESOR

</sql:query>

<html>

<head>

<title>Ejemplo conexion a DB</title>

</head>

<body>

<h2>Results</h2>

<c:forEach var="row" items="${rs.rows}">

Nombre ${row.name}<br/>

Salario ${row.salary}<br/>

</c:forEach>

</body>

</html>



Tambien podemos crear el directorio META-INF a la altura de WEB-INF, conteniendo los archivos:
MANIFEST.MF
Con el contenido:
Manifest-Version: 1.0
Class-Path:

y el archivo: context.xml
con el contenido:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/DBTest">
<Resource name="jdbc/conexionDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/db1"/>

</Context>