lunes, 13 de junio de 2011

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>

sábado, 6 de noviembre de 2010

CMT, BMT y métodos callback de SessionSynchronization

Para este ejemplo estoy usando Netbeans 6.9, Ubuntu 10.04, Glassfish y MySQL Database
En este tutorial vamos a crear Transacciones del tipo BMT(Bean Managed Transaction) y del tipo CMT(Container Managed Transaction)
Para esto creamos un proyecto empresarial llamado Transacciones:


Como primer paso vamos a crear una base de datos en mysql llamada DBTransacciones, para esto usamos el comando create database DBTransacciones 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 Transacciones-ejbPU, como proveedor de persistencia seleccionamos TopLink y en DataSource seleccionamos new DataSource y creamos un nuevo datasource a DBTransacciones, una vez hecho esto seleccionamos como Table Generation Strategy Drop and Create y damos click en Finish.

Hecho esto vamos a crear tres paquetes uno llamado com.ejemplo.cmt, otro paquete llamado com.ejemplo.bmt y uno llamado com.ejemplo.entity, dentro del proyecto EJB

Hagamos unas puntualizaciones con respecto a CMT y BMT, el primero son transacciones que se ejecutan a nivel del contenedor, con el uso de anotaciones a nivel de los métodos o a nivel de las clases. Mientras que en BMT usamos el tipico begin, commit y rollback en nuestro código.
CMT soporta los siguientes tipos de anotaciones:
REQUIRED: Usado en métodos que necesitan ejecutarse en una transacción pero no necesariamente una nueva transaccion.
REQUIRES_NEW: Si una transacción se deben ejecutar en una nueva transacción
SUPPORTS:Cuando los métodos pueden tener codigo que les permita soportar una transaccion.
MANDATORY: Cuando el método debe ejecutarse obligatoriamente en la transacción.
NOT_SUPPORTED:Para métodos que no deben soportar una transacción.
NEVER:Para métodos que no deben ser llamados dentro de una transaccion.

Para este ejemplo de CMT vamos a crear un método con anotaciones de tipo REQUIRED y otro método del tipo REQUIRES_NEW que haremos que falle.
En com.ejemplo.entity creamos un Entity Class llamado persona. Esta clase tendra las variables miembro nombre, direccion, telefono del tipo String, con sus respectivos getters y setters.
Dentro de com.ejemplo.cmt creamos un session bean del tipo stateless, con interface remota llamado UtilitarioCMT. Agregaremos dos business methods, uno llamado agregarPersona y otro llamado cambiarTelefono.Tambien agregamos una inyeccion de Persistence Context con su respectivo EntityManager.
Agregamos luego de la anotacion de stateless la anotacion @TransactionManagement(TransactionManagementType.CONTAINER), para indicar que vamos a utilizar CMT. Agregamos la anotación @TransactionAttribute(TransactionAttributeType.REQUIRED) antes de la función agregarPersona y la anotación @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) antes de cambiarTelefono. Codificamos agregarPersona para que persista un objeto en la base de datos y cambiarTelefono consultará un registro de la base de datos(dato que no existe) y lo actualizará, entonces fallará y no se ejecutará esta transacción, pero la de agregarPersona si se ejecutará.

Entonces el código quedará de la siguiente manera:

package com.ejemplo.cmt;

import com.ejemplo.entity.Persona;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UtilitarioCMT implements UtilitarioCMTRemote {
@PersistenceContext EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void agregarPersona() {
Persona p=new Persona();
p.setId(1L);
p.setDireccion("Amazonas");
p.setNombre("Juliana");
p.setTelefono("7654321");
em.persist(p);
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void cambiarTelefono() {
Persona p=em.find(Persona.class, 12L);
p.setTelefono("1234567");
em.merge(p);
}
}

Luego dejamos el Main del proyecto cliente de la siguiente manera:

package transacciones;

import com.ejemplo.cmt.UtilitarioCMTRemote;
import javax.ejb.EJB;

public class Main {

@EJB private static UtilitarioCMTRemote util;
public static void main(String[] args) {
util.agregarPersona();
util.cambiarTelefono();
}

}

y ejecutamos el proyecto, como veremos aparcerá un error debido a la función cambiarTelefono()

Pero en la base de datos se ha guardado Persona de agregarPersona, debido a que agregarPersona y cambiarTelefono() actuan en dos transacciones diferentes.


Ahora vamos a hacer un ejemplo con BMT, en nuestro paquete com.ejemplo.bmt, creamos un SessionBean del tipo Stateless, con interface remota, llamado UtilitarioBMT. Luego de Stateless agregamos la anotación: @TransactionManagement(TransactionManagementType.BEAN)
y dentro de la clase a mas de la inyeccion de PersistenceContext con su respectivo EntityManager, agregamos una inyección de recurso @Resource UserTransaction ut. Luego creamos la fiuncion crearPersona() y usamos ut.begin() para indicar en donde empieza la transacción y ut.commit() para indicar donde termina la transacción, además de un ut.rollback() en caso de que nos de una excepción y se tengan que deshacer las operaciones hechas. A continuación coloco el respectivo código.

package com.ejemplo.bmt;

import com.ejemplo.entity.Persona;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.UserTransaction;

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class UtilitarioBMT implements UtilitarioBMTRemote {
@Resource UserTransaction ut;
@PersistenceContext EntityManager em;
public void crearPersona() {
try {
ut.begin();
Persona p = new Persona();
p.setDireccion("10 de Agosto");
p.setId(2L);
p.setNombre("Adriana");
p.setTelefono("2256776");
em.persist(p);
ut.commit();
} catch (Exception ex) {
try {
ut.rollback();
} catch (Exception ex1) {
ex1.printStackTrace();
}
ex.printStackTrace();
}
}
}

y nuestro metodo main de la clase Main del proyecto Cliente queda de la siguiente forma:

package transacciones;

import com.ejemplo.bmt.UtilitarioBMTRemote;
import javax.ejb.EJB;

public class Main {
@EJB private static UtilitarioBMTRemote util;
public static void main(String[] args) {
util.crearPersona();

}
}

y arroja la siguiente salida en la Base de Datos:



Vamos a indicar un aspecto extra con respecto a CMT usado en Stateful y es que podemos hacer la llamada a funciones callback antes y después de la ejecución del metodo de la transaccion, para esto vamos a crear el paquete com.ejemplo.cmt.stateful y dentro creamos un SessionBean llamado UtilitarioStateful, de tipo stateful, con interface remota. Dentro colocaremos una función llamada crearPersona y en las interfaces a implementar agregaremos SessionSynchronization, lo cual nos obliga a colocar los métodos afterBegin(),afterCompletion(boolean committed) y beforeCompletion(). Como podemos presumir en base a sus nombres son métodos que se ejecutan antes y después de llamar al metodo de la transacción.El código queda de la siguiente manera:

package com.ejemplo.cmt.stateful;

import com.ejemplo.entity.Persona;
import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.SessionSynchronization;
import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateful
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UtilitarioStateful implements UtilitarioStatefulRemote,SessionSynchronization {
@PersistenceContext EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void crearPersona() {
Persona p=new Persona();
p.setId(1L);
p.setDireccion("Naciones Unidas");
p.setNombre("Karla");
p.setTelefono("987654");
em.persist(p);
}

@Override
public void afterBegin() throws EJBException, RemoteException {
System.out.println("Ya empezó");
}

@Override
public void afterCompletion(boolean committed) throws EJBException, RemoteException {
System.out.println("Ya se acabó");
}

@Override
public void beforeCompletion() throws EJBException, RemoteException {
System.out.println("Antes de que se acabe");
}
}

Finalmente cambiamos nuestro metodo main de la clase Main del Proyecto Cliente a:
package transacciones;

import com.ejemplo.cmt.stateful.UtilitarioStateful;
import com.ejemplo.cmt.stateful.UtilitarioStatefulRemote;
import javax.ejb.EJB;

public class Main {
@EJB private static UtilitarioStatefulRemote util;
public static void main(String[] args) {
util.crearPersona();
}
}

y tenemos la salida en la consola de Glassfish:

Creación de relación Varios a Varios.

Para este ejemplo vamos a utilizar mi post llamado Creacion de Unidad de Persistencia con MySQL en Netbeans.
Creamos un nuevo paquete llamado com.ejemplo.entidades.variosvarios. Dentro creamos una Entity Class llamada Pelicula, que tiene una variable miembro llamada título del tipo String y un Set de tipo Productor llamada productores, Este Set debe tener la anotación @ManyToMany(cascade=CascadeType.ALL),junto con sus repectivos getters and setters .Debe tener el siguiente código:

package com.ejemplo.entidades.variosvarios;

import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Pelicula implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String titulo;
@ManyToMany(cascade=CascadeType.ALL)
private Set productores;

public Long getId() {
return id;
}

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

public String getTitulo() {
return titulo;
}

public void setTitulo(String titulo) {
this.titulo = titulo;
}

public Set getProductores() {
return productores;
}

public void setProductores(Set productores) {
this.productores = productores;
}


public Pelicula() {
}

@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Pelicula)) {
return false;
}
Pelicula other = (Pelicula) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}

@Override
public String toString() {
String cadena = "id:" + id + ";titulo:" + titulo;
for (Productor productor:productores) {
cadena += productor.toString();
}
return cadena;
}

}


Luego creamos una Entity Class llamada Productor, que tiene una variable miembro llamada nombre del tipo String y un Set de tipo Pelicula llamada películas, que debe tener un anotación ManyToMany, junto con sus repectivos getters and setters. Con que el código queda de la siguiente manera:

package com.ejemplo.entidades.variosvarios;

import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Productor implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String nombre;
@ManyToMany(mappedBy = "productores",cascade=CascadeType.ALL)
private Set peliculas;

public Long getId() {
return id;
}

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

public String getNombre() {
return nombre;
}

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

public Set getPeliculas() {
return peliculas;
}

public void setPeliculas(Set peliculas) {
this.peliculas = peliculas;
}



public Productor() {
}

@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Productor)) {
return false;
}
Productor other = (Productor) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}

@Override
public String toString() {
String cadena = "id:" + id + ";nombre:" + nombre;
for (Pelicula pelicula : peliculas) {
cadena += pelicula.toString();
}
return cadena;
}
}

Hecho este código, vamos a crear la clase Utilitario dentro de com.ejemplo.sesion. Ahi hacemos una inyección del persistence Context y usamos un EntityManager para usar la entidad antes creada. Además creamos una funcion llamada relacionVariosVarios, que se encargará de insertar datos (No olvidemos que esta funcion tiene que estar tambien en la interface remota, podriamos usar Insert Code > Add Business Method en Netbeans).Es decir:


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

package com.ejemplo.session;

import com.ejemplo.entidades.variosvarios.Pelicula;
import com.ejemplo.entidades.variosvarios.Productor;
import java.util.HashSet;
import java.util.Set;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
*
* @author santiago
*/
@Stateless
public class Utilitario implements UtilitarioRemote {
@PersistenceContext EntityManager em;

public void relacionVariosVarios() {
Set peliculasJuan=new HashSet();
Set peliculasPedro=new HashSet();
Set peliculasDaniela=new HashSet();
Set peliculasArturo=new HashSet();

Set productoresTitanic=new HashSet();
Set productoresGladiador=new HashSet();
Set productoresTopGun=new HashSet();

Pelicula peliculaTitanic=new Pelicula();
peliculaTitanic.setId(1L);
peliculaTitanic.setTitulo("Titanic");
peliculaTitanic.setProductores(productoresTitanic);

Pelicula peliculaGladiador=new Pelicula();
peliculaGladiador.setId(2L);
peliculaGladiador.setTitulo("Gladiador");
peliculaGladiador.setProductores(productoresGladiador);

Pelicula peliculaTopGun=new Pelicula();
peliculaTopGun.setId(3L);
peliculaTopGun.setTitulo("TopGun");
peliculaTopGun.setProductores(productoresTopGun);

Productor productorJuan=new Productor();
productorJuan.setId(1L);
productorJuan.setNombre("Juan");
productorJuan.setPeliculas(peliculasJuan);

Productor productorPedro=new Productor();
productorPedro.setId(2L);
productorPedro.setNombre("Pedro");
productorPedro.setPeliculas(peliculasPedro);

Productor productorDaniela=new Productor();
productorDaniela.setId(3L);
productorDaniela.setNombre("Daniela");
productorDaniela.setPeliculas(peliculasDaniela);

Productor productorArturo=new Productor();
productorArturo.setId(4L);
productorArturo.setNombre("Arturo");
productorArturo.setPeliculas(peliculasArturo);

productoresTitanic.add(productorJuan);
productoresTitanic.add(productorPedro);
productoresTitanic.add(productorDaniela);

productoresGladiador.add(productorDaniela);
productoresGladiador.add(productorArturo);
productoresGladiador.add(productorPedro);

productoresTopGun.add(productorJuan);
productoresTopGun.add(productorArturo);
productoresTopGun.add(productorDaniela);


em.persist(peliculaTitanic);
em.persist(peliculaGladiador);
em.persist(peliculaTopGun);
}

}

Finalmente el método main del proyecto cliente quedará como:


Relación Uno Varios

Para este ejemplo vamos a utilizar mi post llamado Creacion de Unidad de Persistencia con MySQL en Netbeans.
En esta relación vamos a crear un paquete llamado com.ejemplo.entidades.unovarios



Creamos dentro una Entity Class llamada Producto,


que tendrá las variables miembro:
nombre de tipo String y detalle del tipo Detalle(Clase que ya vamos a crear) que tendra una anotación del tipo ManyToOne con Detalle, generamos sus respectivos getters y setters, junto con un costructor que recibe el id y el nombre. Con lo que la clase nos queda de la siguiente forma:


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

package com.ejemplo.entidades.unovarios;

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

/**
*
* @author santiago
*/
@Entity
public class Producto implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String nombre;
@ManyToOne
private Detalle detalle;

public Long getId() {
return id;
}

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

public Detalle getDetalle() {
return detalle;
}

public void setDetalle(Detalle detalle) {
this.detalle = detalle;
}

public String getNombre() {
return nombre;
}

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

public Producto(){
}

public Producto(Long id, String nombre) {
this.id = id;
this.nombre = nombre;
}



@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Producto)) {
return false;
}
Producto other = (Producto) 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.unovarios.Producto[id=" + id + "]";
}

}


Luego creamos otra Entity Class llamada Detalle que tendrá como variables miembro descripción del tipo String y una Lista de tipo Producto llamada productos que tiene una anotación OneToMany. Tambien generamos getters y setters. De tal manera que nos quede de la siguiente manera:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

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

package com.ejemplo.entidades.unovarios;

import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

/**
*
* @author santiago
*/
@Entity
public class Detalle implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String descripcion;
@OneToMany(mappedBy="detalle",cascade=CascadeType.ALL)
private List productos;

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;
}

public List getProductos() {
return productos;
}

public void setProductos(List productos) {
this.productos = productos;
}




@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Detalle)) {
return false;
}
Detalle other = (Detalle) 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.unovarios.Detalle[id=" + id + "]";
}

}

Hecho este código, vamos a crear la clase Utilitario dentro 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 relacionUnoVarios, que se encargará de insertar datos (No olvidemos que esta funcion tiene que estar tambien en la interface remota, podriamos usar Insert Code > Add Business Method en Netbeans). Es decir:


package com.ejemplo.session;

import com.ejemplo.entidades.unovarios.Detalle;
import com.ejemplo.entidades.unovarios.Producto;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class Utilitario implements UtilitarioRemote {
@PersistenceContext EntityManager em;

public void relacionUnoVarios() {
Detalle detalle = new Detalle();
Producto producto1 = new Producto();
producto1.setId(6L);
producto1.setNombre("Cafe");
producto1.setDetalle(detalle);
Producto producto2 = new Producto();
producto2.setId(7L);
producto2.setNombre("Té");
producto2.setDetalle(detalle);
List productos = new ArrayList();
productos.add(producto1);
productos.add(producto2);
detalle.setId(10L);
detalle.setDescripcion("Esta es una prueba de detalles");
detalle.setProductos(productos);
em.persist(detalle);
}

}

El metodo Main tiene el siguiente código:

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.relacionUnoVarios();
}
}

y las consultas a las tablas tienen la siguiente información