martes, 14 de junio de 2011

JPA – Paso 2: agregando anotaciones de Persistencia

Siguiendo con el tutorial anterior, ya tenemos preparadas las clases a nivel de POJOs, es decir, clases base java con la información de las entidades u objetos a ser persistidos, es de notar que también hemos implementado en código fuente las relaciones entre las entidades.

Ahora nos vamos a enfocar en las anotaciones que vamos a agregar a nuestro código con el fin de preparar nuestra anterior implementación para que pueda soportar y llevar a cabo la implementación automática de la base de datos, es decir, que pueda hacer uso de JPA. Para ello, la implementación del modelo de clases debe seguir el modelo planteado en el tutorial anterior, como se observa en la siguiente imagen.
image
Para empezar, todas las clases (Empleado, TipoTelefono, Agenda, PKAgenda) del proyecto deben implementar la interfaz Serializable, siguiendo la nomenclatura Java, tendríamos algo así:
image  image
image  image
El objetivo de implementar la interfaz Serializable es poder enviar las instancias de estas clases por algún canal, en este caso, será para su transporte y posterior consumo.
Ahora empezaremos con las anotaciones de persistencia, las clases Empleado y TipoTelefono tienen básicamente la misma naturaleza, así que analizaremos en detalle las anotaciones de la clase Empleado ya que serán las mismas para la clase TipoTelefono.
La primera anotación a usar es @Entity, esta anotación ordena que la clase en definición será persistida, es decir, que se convertirá en una tabla en la base de datos. @Entity se ha de poner justo antes de la definición de clase, como se observa en la figura:
imageRecuerden que, para que esta anotación no tenga errores, será necesario hacer el import adecuado, como se observa en la cuarta línea de código de la imagen anterior.
La siguiente anotación a usar es @Id, esta anotación define cual es el campo primary key (PK) ya que se ha de colocar antes de la definición del atributo en la clase correspondiente. Colocando la anotación como se observa en la figura, estamos definiendo el atributo codEmpleado de tipo long, como el campo PK de la tabla Empleado, recuerden que @Entity define a la clase Empleado como la tabla Empleado.
image
Como en la mayoría de los casos será necesario dejar a la base de datos la responsabilidad de ir creando los valores de los campos PK, en nuestro caso dejaremos que la base de datos lo haga, para ello usaremos la anotación @GeneratedValue y definiremos la estrategia de generación en Identity, como se observa claramente en la imagen siguiente.
image Esta anotación será necesaria sólo si la base de datos va a ser la encargada de generar los códigos del campo PK, si los códigos serán registrados de manera manual, no será necesario usar esta anotación.
Otra anotación a usar, con el fin de definir claramente el nombre del campo a usar en la base de datos, es la anotación @Column, en dicha anotación usaremos como valor opcional el de name y le daremos el valor que deseamos como nombre en la base de datos.
image
Ahora veamos las anotaciones para el atributo nombre, en este atributo sólo usaremos dos anotaciones, @Basic para dar la orden explicita de persistir dicho campo, y @Column para la definición del nombre del campo en la base de datos.
image
Finalmente, recordemos que en la clase Agenda, hemos definido la relación entre Agenda y Empleado con la instancia de la clase Empleado, a dicho objeto lo hemos llamado empleado, como se observa en la siguiente imagen.
image
Es este nombre de objeto empleado, no el de la clase que es Empleado, el que debemos tener en cuenta para la ultima anotación. La anotación final a usar será @OneToMany y su valor opcional será mappedBy, valor al cual asignaremos el nombre del atributo en la clase de destino, en este caso, empleado.
image
Exactamente las mismas indicaciones hemos de seguir para las anotaciones de la clase TipoTelefono, ya que esta clase tiene la misma estructura que la clase Empleado. Tenemos entonces nuestras clases con las anotaciones finales de persistencia, tal y como podemos apreciar en las imágenes siguientes.
image image
Ahora nos enfocaremos en las dos clases restantes, la primera será PKAgenda ya que es esta clase la que contiene la información y definición de la PK múltiple de la clase Agenda. Recuerden que sólo en casos de tener múltiples PKs en una clase será necesario el uso de una clase para la definición de dichos campos, sólo en caso de PKs múltiples.
La primera anotación a usar será @Embeddable e irá en el mismo lugar donde pusimos @Entity en las clases anteriores, se usa @Embeddable porque las instancias de esta clase serán incrustadas en otra clase y no solamente estarán como definición de relaciones, además no se hace uso de @Entity porque esta clase no dará pie a la creación de una tabla.
image
Las otras dos anotaciones a usar son @Basic, con una observación extra, tendrá optional=false con el fin de declarar, como en cualquier campo PK, que no es posible que este campo este con valor null. Además tenemos otra anotación, @Column la importancia de este campo en este momento, radica en que los nombres usados coinciden con los de las definiciones de nombre de campos dadas en las clases Empleado y TipoTelefono.
image
Como último paso, ahora agregaremos las anotaciones finales, las que corresponden a la clase Agenda. Entre estas anotaciones se encuentra @Entity, obviamente es para declarar que nuestra clase Agenda será persistida como una tabla con el mismo nombre.
La siguiente anotación es @EmbeddedId, esta anotación precede a la instancia de la clase PKAgenda, y la declara como elemento incrustado cuya definición se encuentra en la descripción de la clase de destino (PKAgenda) y además como clave primaria (PK), tal y como se puede apreciar en la siguiente imagen:
image
Ahora, para el atributo telefono, serán necesarias dos anotaciones, @Basic, para declarar que el campo telefono sea persistido y @Column con el fin de declarar explicitamente el nombre del campo de persistencia.
image
Finalmente, las dos instancias de las clases Empleado y TipoTelefono, necesitan sus propias anotaciones, la primera será @ManyToOne, si leemos el diagrama de clases puesto al inicio y lo leemos desde Agenda hacia Empleado veremos que la lectura va de muchos a uno, por eso usamos la anotación correspondiente @ManyToOne, el optional = false es porque este valor no puede ser null, es decir, siempre ha de existir.
La anotación final será @JoinColumn, anotación que define una o varias llaves foráneas, en este caso será solo una, lo importante en esta anotación radica en que name define el nombre de la columna que va a gestionar la relación, note como este valor corresponde al valor de @Column ubicado en la clase PKAgenda, esto quiere decir que este valor es PK y FK a la vez, el valor de referencedColumnName es el valor de referencia en la tabla de origen, es decir, en Empleado, las opciones insertable y updatable han de estar en false porque no se pueden hacer modificaciones ni inserciones de nuevos elementos desde este ámbito.
El código finalmente luce de esta forma:
@ManyToOne(optional=false)
@JoinColumns({
    @JoinColumn(name = "codEmpleado", referencedColumnName = "codEmpleado", insertable = false, updatable = false)})
private Empleado empleado;

@ManyToOne(optional=false)
@JoinColumns({
    @JoinColumn(name = "codTipoTelefono", referencedColumnName = "codTipoTelefono", insertable = false, updatable = false)})
private TipoTelefono tipoTelefono;

image
Como pasos finales y complementarios crearemos una base de datos en MySQL, la base de datos será agendadb, tal y como se detalla en el tutorial del primer web service y JPA. Como se observa en la siguiente imagen, la base de datos no tiene ninguna tabla en su interior.
image
Ahora agregaremos una unidad de persistencia, para ello necesitamos dar un clic derecho en el nombre del proyecto, luego elegimos nuevo y finalmente la última opción, la opción de otros.
image
Del cuadro emergente seleccionamos en el panel de la izquierda la carpeta de persistencia, y en el de la derecha la Unidad de Persistencia, en el siguiente cuadro crearemos un nuevo Data Source, por nombre le daremos también agendadb y lo apuntaremos a la base de datos recién creada.
SNAGHTML351b1a3 SNAGHTML350bf3a[4]
SNAGHTML355d402
Con estos pasos tenemos una nueva unidad de persistencia recién creada cuyo fin es gestionar la conexión a la base de datos que es donde se representarán las clases y se creará el modelo de persistencia.
SNAGHTML3582127
Ahora crearemos los respectivos EJBs de sesión, para ello en el mismo menu anterior elegimos ahora Session Beans For Entity Classes…, en el cuadro emergente seleccionamos todas las clases y las pasamos al panel de la derecha, como se observa en las siguientes imágenes. En la siguiente ventana cambiamos el nombre del paquete para tener cierto orden en la generación de archivos, además marcamos la creación de interfaces en local y no en remoto, esto es porque los EJBs serán consumidos por el web service de manera local y no remota.
image SNAGHTML368fc4a
SNAGHTML36e75ad
Como parte final crearemos un Web Service, con un clic derecho en el nombre del proyecto, seleccionamos nuevo y luego Web Service…, en la ventana siguiente cambiamos el nombre del Web Service por uno adecuado, así como el paquete donde se creará el archivo del Web Service, además configuramos la creación del Web Service en base a un Session Bean existente, elegimos el de Agenda y aceptamos la creación del Web Service.
image  SNAGHTML3751881
SNAGHTML376b443 SNAGHTML3772fc8
Para culminar el proyecto, ejecutamos la opción Clean and Build o Limpiar y Construir, luego Deploy y tenemos el proyecto concluido y desplegado en el servidor, para confirmar la ejecución correcta del código bastará con observar el resultado en la base de datos.
image
Otra forma de verificar la correcta creación del modelo es por medio del Workbench, elegimos la opción de crear un modelo EER de una base de datos existente. Como se observa en la imagen el modelo se ajusta perfectamente a lo planteado originalmente, estos son los pasos a seguir con el fin de plasmar el modelo planteado haciendo uso de JPA.
image image
En las siguientes entregas nos enfocaremos en como consumir el Web Service creado con el uso de interfaces web, además iremos creando nuevos métodos en el Web Service para ajustarlo a las necesidades de la interfaz.

1 comentario:

  1. Buenas Profesor Como Puedo Crear una Entidad que tenga dos FK (codAlumno, codCargaAcademica) y dos Campos ( Fecha, Hora) y que entre los 4 formen EL PRIMARY KEY , no estoy muy seguro en relacion a las anotaciones ni como crear mi Entidad, POST : Es la ultima parte que me falta en mi proyecto si eso no creo poder avanzar. Gracias

    ResponderEliminar