0.1 JPA.docx

207
Desarrollo de Aplicaciones Web Índice . Unidad 1 Struts 2 Tema 1. Struts 2 Gestión de componentes RIA Etiquetas Ajax en Struts 2 Librerías de Dojo y Struts 2 Librerías JQuery Struts 2 Tema 2. Struts 2: Tópicos de Seguridad y validación Etiqueta Token Validaciones Unidad 2 JPA Tema 1. Introducción a la API de Persistencia Entidad Metadata EntityManager Unidad de Persistencia Operaciones Básicas Transacciones Ciclo de vida de la entidad Tema 2. OR-Mapping con JPA Anotaciones Manejo de la llave primaria Generacion de la llave primaria Llave primaria compuesta Objetos Embebidos Tema 3. Relaciones entre entidades Conceptos Básicos Relacion Many To One

Transcript of 0.1 JPA.docx

Page 1: 0.1 JPA.docx

Desarrollo de Aplicaciones WebÍndice .

Unidad 1 Struts 2Tema 1. Struts 2 Gestión de componentes RIA

Etiquetas Ajax en Struts 2 Librerías de Dojo y Struts 2 Librerías JQuery Struts 2

Tema 2. Struts 2: Tópicos de Seguridad y validación Etiqueta Token Validaciones

Unidad 2 JPATema 1. Introducción a la API de Persistencia

Entidad Metadata EntityManager Unidad de Persistencia Operaciones Básicas Transacciones Ciclo de vida de la entidad

Tema 2. OR-Mapping con JPA Anotaciones Manejo de la llave primaria Generacion de la llave primaria Llave primaria compuesta Objetos Embebidos

Tema 3. Relaciones entre entidades Conceptos Básicos Relacion Many To One Relacion One To One Bidireccionalidad de la relación One to One Relacion One to Many Relacion Many to Many Operación de Fetch

Tema 4. Lenguaje de Consultas JPQL

Page 2: 0.1 JPA.docx

Introduccion a JP-QL Consultas Dinamicas Consultas nombradas Uso de parámetros Ejecucion de Queries Sintaxis de JPQL

Unidad 3 JSF

Tema 1. Arquitectura de JSF, Configuración y estructura básica introducción a JSF Arquitectura de JSF Ciclo de vida de un request Facelets Managed Bean Lenguaje de Expresiones JSF Backing Beans

Tema 2. Componentes de Interfaz de usuario Introducción Arquitectura de componentes UI Librería Core Librería HTML Librería User Interface Librería de componentes compuestos

Tema 3. Conversiones, Validaciones y Eventos Introducción El sistema de conversión de JSF El sistema de validación de JSF El sistema de Mensajes de JSF El modelo de eventos de JSF

Tema 4. Tópicos avanzados de JSF I JSF y AJAX Integracion JSF +JPA Empleando otras implementación e JSF

Tema 5. Tópicos avanzados de JSF II Tablas JSF. Facets, dateTable y panelGrid Mantenimiento de Tablas

Bibliografías

RED DE CONTENIDOS

Page 3: 0.1 JPA.docx

Unidad 1 Struts 2

Page 4: 0.1 JPA.docx

Tema 1. Struts 2 Gestión de componentes RIA

LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, el alumno, empleando opciones de AJAX y facilidades avanzadas que proporciona el framework Struts-2, construye una aplicación web de n-capas y la despliega dentro de un servidor de Aplicaciones Java EE compatible.

ACTIVIDADES PROPUESTAS Los alumnos implementan una sencilla aplicación web para recordar los conceptos de Struts 2. Los alumnos implementan opciones de una aplicación web con Struts 2 y para utilizar las

funcionalidades de Ajax seleccionan indistintamente el plug-in de Dojo o de jQuery. Los alumnos implementan una aplicación web con Struts 2 que utiliza la etiqueta Token para evitar el

problema del “doble submit”. Los alumnos implementan validaciones en los formularios de las aplicaciones web desarrolladas con

Struts 2.

TEMA 1: STRUTS 2: GESTIÓN DE COMPONENTES RIA. Struts2 atiende una petición del tipo Request de la siguiente forma:

a. El Request es interpretado por el DispatcherFilter y determina que Action y que conjunto de Interceptors invocar.

b. Cada Interceptor ejecuta sus acciones previas a la ejecución del método de Action a invocar Si el Interceptor I18nInterceptor intercepta el Action: Se ubicará en la session del usuario un

objeto Locale para utilizar i18n. Si el Interceptor ValidationInterceptor intercepta el Action: Se ejecutan la reglas de validación

definidas sobre el Action Si el Interceptor AnnotationValidationInterceptor intercepta el Action: Se chequea en el método

a invocar del Action si tiene la anotación @SkipValidation, en cuyo caso no se realizan validaciones.

c. Es ejecutado el método anotado con @Before en el Action d. Es invocado el método del Action. e. Es ejecutado el método anotado con @After en el Action f. Es ejecutado el método anotado con @BeforeResult en el

Action g. Cada Interceptor ejecuta sus acciones posteriores a la

ejecución del método de Action a invocar Si el Interceptor ModelDrivenInterceptor

intercepta el Action: Luego de la ejecución del Action se ubicara en el value stack el modelo que provee el Action.

Si el Interceptor ParametersInterceptor intercepta el Action: Los parametros provenientes del Request se ubican en el value stack

h. Se examina el resultado obtenido del Action y se determina el Result correspondiente.

i. Mediante el Result determinado se genera la vista, y según la configuración definida sobre él se invoca el proceso de generación de la vista.

j. La vista generada retorna al cliente.1.1 ETIQUETAS AJAX Y STRUTS 2

Page 5: 0.1 JPA.docx

Consultando la Wikipedia: Ajax, acrónimo de Asynchronous JavaScript And XML (JavaScript asíncrono y XML), es una técnica de desarrollo web para crear aplicaciones interactivas o RIA (Rich Internet Applications). Estas aplicaciones se ejecutan en el cliente, es decir, en el navegador de los usuarios mientras se mantiene la comunicación asíncrona con el servidor en segundo plano. De esta forma es posible realizar cambios sobre las páginas sin necesidad de recargarlas, lo que significa aumentar la interactividad, velocidad y usabilidad en las aplicaciones. Ajax es una tecnología asíncrona, en el sentido de que los datos adicionales se requieren al servidor y se cargan en segundo plano sin interferir con la visualización ni el comportamiento de la página. JavaScript es el lenguaje interpretado (scripting language) en el que normalmente se efectúan las funciones de llamada de Ajax mientras que el acceso a los datos se realiza mediante XMLHttpRequest, objeto disponible en los navegadores actuales. En cualquier caso, no es necesario que el contenido asíncrono esté formateado en XML. Ajax es una técnica válida para múltiples plataformas y utilizable en muchos sistemas operativos y navegadores dado que está basado en estándares abiertos como JavaScript y Document Object Model (DOM). La respuesta del servidor puede ser un formato XML, HTML, texto puro, otro Script o cualquier otro formato que el JavaScript invocador requiera.

Struts 2 soporta AJAX de dos maneras fundamentales: Cuando se devuelve un “Response” vía “Stream” de datos Cuando se devuelve un “Response” vía JSON (JavaScript Object Notation )

1.2 LIBRERÍA DE TAGS PARA DOJO STRUTS2: Para usar los tags de AJAX se debe:

Incluir el plugin de Dojo en el folder /WEB-INF/lib (distribuido con Struts2 ) . Agregar la taglib a cada página:

<%@taglib prefix=”sx” uri=”/struts-dojo-tags %>

Incluir el tag <sx:head> en la página y configurarlo para propósitos de desempeño o de depuración.

Muchos ejemplos se pueden encontrar en la documentación y guías del proyecto Struts2.

Los tags para manejo de funciones AJAX son: a autocompleter bind datetimepicker div head submit tabbedPanel textarea tree treenode

Tag <sx:autocompletar>

Page 6: 0.1 JPA.docx

Este tag es un combo box que permite autocompletar el texto ingresado en la caja de entrada. Si se emplea un “action” para cargar el autocompletar, la salida de dicha “action” debe ser en formato JSON. Este tag emplea las siguientes reglas para ubicar la fuente de datos:

a) Si la respuesta en un arreglo, se asume que contiene elementos de dos dimensiones:

b) Si se especifica un valor en el atributo “dataFieldName” y la respuesta tiene un campo con dicho nombre, se asume que esa es la fuente de datos, la cual debe ser un arreglo de elementos de dos dimensiones o en todo caso un Map. Por ejemplo, asumiendo que “datafieldName” tiene el valor “state”:

O como mapa:

c) Si existe un campo que comienza con el valor especificado en el atributo “name”, se asume que esa es la fuente de datos. Por ejemplo, asumiendo que “name” tiene el valor “state”:

d) Se emplea el primer arreglo que se encuentra. Ejemplo:

e) Si hay un Map, se usa:

Ejemplo: Crear un action que tenga el código siguiente:

Page 7: 0.1 JPA.docx

No olvidar los “getter/setter”.

Observe que hay una lista que se llama “paises” y que además hay una variable que se llama “pais”.

Luego, crear una página que utilice los tags:

Observe que: En la línea 2 se requiere definir la “taglib” de Struts2 En la línea 3 se requiere definir la “tablig” de los tags que se manejan con Dojo. También, es importante hacer la declaración de <sx:head /> para que se incluyan las librerías de

JavaScript necesarias. Luego, en la línea 13 se utiliza el tag de “autocompletar”. Considere que el atributo “list” se asocia

vía OGNL con la variable “países” del Action “Ejemplo01” y que el atributo “name” se asocia a la variable “país” cuando se seleccione algún país de la lista.

Si se escribe la primera letra de algún país, debe aparecer la lista desplegable con los países respectivos:

Page 8: 0.1 JPA.docx

Tag <sx:datetimepicker> Este tag muestra un calendario dentro de una ventana contenedora. La sintaxis que soporta el atributo “displayFormat” es:

Ejemplo:

Page 9: 0.1 JPA.docx
Page 10: 0.1 JPA.docx

Tag <sx:div> Este tag genera una marca HTML de tipo <div> que permite cargar contenido utilizando llamadas XMLHttpRequest mediante el Framework de Dojo. Cuando se coloca un valor a “updateFreq”, el timer interno inicia de forma automática y recarga el contenido de la zona cada vez que se produzca el periodo de refresco ( en milisegundos ). Se pueden emplear “Topics” para detener (stopTimerListenTopics) o iniciar (startTimerListenTopics) el timer. Cuando se usa este tag dentro de un “tabbedpanel”, cada “div” se convierte en un “tab” por lo que en este caso, existen algunos atributos específicos: refreshOnShow : el contenido del “div” es cargado cuando se selecciona el “tab”. closable : el “tab” tiene un botón de close. preload: el contenido del “div” se carga inmediatamente después que a página es cargada.

Tag <sx:tabbedPanel> Este tag es un componente primario de AJAX, donde cada tab puede cargar contenido local o remoto ( que se refresca cada vez que el usuario selecciona el tab ). Si se coloca el valor de “trae” a “useSelectedTabCookie”, el “id” del “tab” se almacena en un cookie durante la activación. Cuando se regresa a dicha vista, el cookie se lee y el “tab” se activa de nuevo. Si se desea emplear las características de cookie, se debe asegurar de proporcionar un único “id” para el componente. Ejemplo:

Page 11: 0.1 JPA.docx

Observe que en la línea 23, el tab número dos tiene contenido “remoto” ( desde una URL ) por lo cual, los tags que están inmersos no se mostrarán. El atributo “preload” indicará si dicho contenido se cargará al momento de seleccionar el tab o al momento de cargar todo el panel.

Page 12: 0.1 JPA.docx

Tag <sx:tree> Este tag muestra un árbol con soporte AJAX. Requiere del soporte del tag <sx:treenode> Tag <sx:treenode> Muestra una hoja dentro del árbol con soporte a AJAX. Si el árbol se genera estáticamente: rootNode: es el nodo padre desde donde se origina el árbol. nodeIdProperty : propiedad que permite obtener el id del nodo actual. nodeTitleProperty: propiedad para obtener el título del nodo actual. childCollectionProperty: propiedad que retorna los nodos hijos del nodo actual.

Page 13: 0.1 JPA.docx

Observe que el anidamiento de los tags <sx:treenode > indica la jerarquía dentro del árbol.

Si el árbol se genera dinámicamente:

Page 14: 0.1 JPA.docx

id : es el id del nodo title: es la etiqueta a ser mostrada en el nodo

Ejemplo de tree dinámico:

Crear una clase “auxiliar”:

No olvidar los getter/Setter. Observe que es una clase simple. Crear un Action :

Page 15: 0.1 JPA.docx

Observe que esta clase no tiene getter/setter y se apoya en la clase auxiliar definida en el paso anterior. Ahora se genera la página JSP:

Page 16: 0.1 JPA.docx

1.3 LIBRERÍA DE TAGS PARA JQUERY STRUTS2: Para obtener el plug-in se debe ingresar a Google Code en la ruta siguiente http://code.google.com/p/struts2-jquery/ y descargar los .jar necesarios de la zona ubicada al lado derecho de la página ( como se muestra en el gráfico ).

Luego proceder a importar el .jar dentro del proyecto.

Page 17: 0.1 JPA.docx

Para usar los tags de AJAX se debe: Incluir el plugin de jQuery en el folder /WEB-INF/lib (como se muestra en la imagen anterior ) . Agregar la taglib a cada página:

<%@taglib prefix=”sj” uri=”/struts-jquery-tags %> Incluir el tag <sj:head> en la página.

Muchos ejemplos se pueden encontrar en la documentación de Google Code. Los tags para manejo de funciones AJAX son: TabbedPanel Datepicker Dialog Accordion Autocompleter Button Buttonset Progressbar Slider Grid Richtext Editor Charts Spinner

Tag <sj:autocompletar> Este tag genera un campo de tipo autocompletar que puede cargar contenido via JSON o manejar una lista. Para personalizar los temas se debe ver la documentación del tah <sj:head>. Ejemplo: Generar una clase Action que maneje una lista de países:

Page 18: 0.1 JPA.docx

No olvidar los “getter/setter”. Ahora, genere una página JSP que haga uso del tag para mostrar la lista de países:

Observe que: En la línea 2 se requiere definir la “taglib” de Struts2. En la línea 3 se requiere definir la “tablig” de los tags que se manejan con jQuery. Tambien, es importante hacer la declaración de <sj:head /> para que se incluyan las librerías de javascript necesarias.

Page 19: 0.1 JPA.docx

Luego, en la línea 13 se utiliza el tag de “autocompletar”. Considere que el atributo “list” se asocia vía OGNL con la variable “paises” del Action “Ejemplo01” y que el atributo “name” se asocia a la variable “pais” cuando se seleccione algun país de la lista.

Si se escribe la primera letra de algun país, debe aparecer la lista desplegable con los nombres de países que contienen dicha letra:

ACTIVIDAD: Cambiar el “theme” para ver como se altera la apariencia de la caja. El tema se cambia en la zona <sj:head> de la página.

Tag <sj:datepicker> Este tag sirve para mostrar un calendario. Requiere que se agrega la librería commons-lang.2.3jar para evitar errores de ClassNotFoundException al momento de ejecutar el ejemplo. Tenga en cuenta que se coloca atributos de “theme” y “locale” en la zona de cabecera.

Page 20: 0.1 JPA.docx

El ejemplo está tomado de la página de documentación de Google (ver referencia).

Page 21: 0.1 JPA.docx
Page 22: 0.1 JPA.docx

ACTIVIDAD: Pruebe cambiar los “themes” en la cabecera de la página para observar cómo se visualizan los calendarios.

Tag <sj:tabbedpanel> Este tag genera un panel con varias hojas que pueden cargar contenido vía invocaciones Ajax. Ejemplo: Generar una página JSP que emplee dicho tag:

Page 23: 0.1 JPA.docx

Completar los tags faltantes al final de la página. Probar

Page 24: 0.1 JPA.docx

ACTIVIDAD: Generar un tab con contenido remoto. Este éste caso usamos el atributo “selectedTab” teniendo en cuenta que los “tabs” se numeran desde cero.

Page 25: 0.1 JPA.docx

TEMA 2: TÓPICOS DE SEGURIDAD Y VALIDACIÓN EN STRUTS 2 2.1 ETIQUETA <s:token> Struts 2 proporciona el soporte necesario para evitar el doble submit de un formulario al incorporar un tag personalizado en las páginas web y un interceptor que previene los requests duplicados. Struts 2 emplea la siguiente lógica para evitar el procesamiento de requests duplicados: a) Se codifica la página web con un token embebido como campo oculto. b) Se coloca dicho token único dentro de la sesión del usuario. c) Se envía la página al navegador del usuario. d) Cuando el formulario es enviado, los dos tokens son comparados. e) Si los tokens no son idénticos, se retorna el resultado “invalid.token”.

Ejemplo:

Page 26: 0.1 JPA.docx

La línea 5 introduce un nuevo tag de Struts2 llamado “<s:token>”, el cual se va a encargar de evitar que la página ejecute un doble submit. Para manejar el request, se debe declarar un interceptor. Los interceptores interrumpen la ejecución del request y proporcionan el manejo necesario antes que se ejecute el código correspondiente a la acción. El el struts.xml se registra la acción y se debe declarar el interceptor “token” (por defecto no está dentro del defaultStack) y los posibles resultados:

Observe que el Action está haciendo referencia al interceptor llamado “token” y al “defaultStack” (líneas con el tag <interceptor-ref> del listado).

Si todo está bien, se invoca a la página “plantilla-fin.jsp”. Si hay errores de validación se invoca nuevamente a la página “plantilla-inicio.jsp”. Finalmente, si se ejecuta un doble submit, el interceptor invocará a la página “plantilla-

invalidtoken.jsp”.

Page 27: 0.1 JPA.docx

Si el usuario ejecuta el submit y luego presiona el botón de “back” para ejecutar un nuevo submit, se debe mostrar la siguiente pantalla:

Una solución más transparente para el problema del doble submit es el uso del interceptor “tokenSession”, el cual maneja una lógica un poco más inteligente: en lugar de devolver el “invalid.token”, bloquea el request duplicado y devuelve la respuesta del primer request.

Para ello, debe declararse el interceptor de la siguiente forma:

2.2 VALIDACIONES EN STRUTS 2 Struts 2 proporciona dos Interfaces (implementadas por ActionSupport) en el framework: Validateable : que contiene un único método cuya firma es void validate(). La clase ActionSupport contiene una implementación por defecto que permite validar mediante configuraciones basadas en XML o en anotaciones.

ValidationAware: proporciona un grupo de métodos usados para recolectar mensajes de error relacionados a campos del formulario o propiedades de la clase Action en general. Tambien se emplea para recolectar mensajes informativos y determinar si se presentan errores.

Page 28: 0.1 JPA.docx

Las dos interfaces colaboran dentro del workflow de Struts2, específicamente en el stack de interceptores: interceptor “validation” e interceptor “workflow”. Si la validación es satisfactoria, se ejecuta el método respectivo de la clase Action invocada. En caso que la validación falle, se retorna el resultado denominado “input”. Si no se define el resultado para “input”, el framework genera un error durante la ejecución. En el siguiente gráfico se muestra la arquitectura de validación de Struts 2, la cual está conformada por tres componentes principales: Datos: (domain data) que son las propiedades que residen en el Action de Struts 2 y que se cargan cuando comienza la ejecución de la acción. Metadata de validación: que sirve para asociar cada propiedad con las validaciones necesarias a ser realizadas en tiempo de ejecución. El framework permite que se utilice un archivo XML o anotaciones java. Validadores: Un validador es un componente reutilizable que contiene la lógica para ejecutar la validación.

2.2.1 VALIDACIÓN MANUAL

Page 29: 0.1 JPA.docx

Implementar el método void validate() en una clase Action. Generar un formulario: “ejemplo01.jsp”

Page 30: 0.1 JPA.docx

Observe que el formulario llama a un “action” ( que debe estar registrado en el struts.xml ) Además observe que entre las líneas #11 a la #15 hay un IF que muestra los mensajes de error ( si es que hubieran ). Estos mensajes son colocados por la validación realizada en el Action.

Ahora, escribir la clase “Action” ( no olvidar los getter/setter de las variables ):

Page 31: 0.1 JPA.docx

Ejecutar la aplicación:

Page 32: 0.1 JPA.docx

Si se presiona el botón “Registrarse” sin haber ingresado ningún dato, debe salir la siguiente pantalla (mostrando el mensaje de validación):

Page 33: 0.1 JPA.docx

Observe el mensaje debajo del campo que se ha validado. Una vez solucionado el problema, presionamos nuevamente el botón “Registrarse” y la aplicación debería seguir su curso normal. 2.2.2 VALIDACION USANDO XML Una validación más compleja utilizando las facilidades que nos brinda el framework de Struts-2. Crear una página JSP similar al caso anterior.

Escribir la clase “Action” pero sin el método “validate” del ejemplo anterior (no olvidar los getter/setter):

Page 34: 0.1 JPA.docx

Escribir las validaciones de los campos “nombre” y “apellido”. Para ello se debe crear un archivo XML a la misma altura en donde está definido el Action. El nombre del archivo debe seguir la norma: <Nombre del Action>-validation.xml En este caso sería Ejemplo2-validation.xml cuyo contenido es:

Page 35: 0.1 JPA.docx

Este archivo tiene dos formas de validación: Usando “<validator>”: observe que el nombre del campo a validar se pasa como parámetro. Usando “<field>”: observe que el nombre del campo se asigna directamente en el atributo “name”.

Cuando las validaciones son muy simples, no interesa cual de las dos formas se utilice, pero a medida que las validaciones se hacen más complejas, es preferible emplear la forma “field” que hace mucho más entendible la lectura del archivo. 2.2.3 VALIDACIONES MÁS COMPLEJAS CON XML Sobre la base del ejemplo anterior, se hará un poco más complejo el contenido del archivo XML de validaciones. El action es bastante sencillo ( no olvidar los getter/setter):

La parte importante de este ejemplo es el archivo de validación XML que utiliza éste Action:

Page 36: 0.1 JPA.docx

CIBERTEC CARRERAS PROFESIONALES La parte importante de este ejemplo es el archivo de validación XML que utiliza éste Action: Note que ahora se utiliza el formato <field> para validar dos cosas:

Que se ingrese un texto en el campo “nombre” Que el texto ingresado cumpla con una longitud mínima.

Observe que se pasa como parámetro “minLength” y que en el texto del mensaje se puede emplear expresiones de OGNL para recuperar valores que se encuentran en el stack.

2.2.4 VALIDACIONES USANDO ARCHIVO .properties

Page 37: 0.1 JPA.docx

En este ejemplo, los textos de los mensajes se tomarán desde un archivo .properties (considerar que lo mismo sirve para i18N ). Crear una clase Action (no olvidar los getter/setter ):

Configurar el archivo de validación: Ejemplo4-validation.xml

Page 38: 0.1 JPA.docx

Y generar un archivo .properties a nivel de PAQUETE:

Cuyo contenido es:

Page 39: 0.1 JPA.docx

Note que el texto tiene expresiones OGNL que referencian a parámetros propios del archivo de validación. El resultado es similar a la siguiente pantalla:

2.2.5: VALIDACIONES DISPONIBLES EN STRUTS-2 requiredstring: Tiene un parámetro adicional que es “trim” el cual por defecto es TRUE. La particularidad de este parámetro es que sólo ejecuta el TRIM para efectos de verificación de la longitud, más no para enviar el valor al Action (OJO con esto). stringlength: Tiene parámetros como “trim”, “maxlength”, “minlength”. En el caso del “trim”, se comporta igual que en “requiredstring”. Ejemplo:

Page 40: 0.1 JPA.docx

int: Tiene como parámetros “min” y “max”. Si se especifican los dos parámetros, el framework verifica que el valor ingresado esté dentro del rango ( intervalo cerrado ). double: Permite comparaciones de rango que incluyen o no a los extremos. Tiene como parámetros a: “minInclusive”, “maxInclusive”, “minExclusive”, “maxExclusive” en donde cualquier combinación es permitida. email: Es una subclase del validador “regex” y permite validar la sintaxis de una dirección de correo electrónico. url: A diferencia del validador “email”, este validador no es una subclase de “regex”. Al contrario, utiliza las características del constructor de java.net.URL para verificar la sintaxis de una dirección URL. date: Tiene los parámetros “min” y “max” para validar rangos de fechas. Recordar que el servidor recibe los parámetros en formato STRING. regex: Este validador acepta expresiones regulares (en sintaxis Java) y valida el valor ingresado contra la expresión dada. Si el campo a ser validado es obligatorio se debe usar el validador “requiredstring”. Este validador acepta parámetros “trim”, “caseSensitive” cuyo valor por defecto es TRUE. expression y fieldexpression: Ambos validadores toman expresiones OGNL en el parámetro “expression” para evaluarlo y determinar si hubo éxito o falla.

Se recomienda realizar evaluaciones más complejas dentro del método “validate()” antes que en el archivo –validation.xml. Se puede combinar la validación en el código con el archivo XML simplemente invocando a : super.validate(). Ejemplo:

Page 41: 0.1 JPA.docx

2.2.6: VALIDACION USANDO ANOTACIONES También se puede utilizar las validaciones vía anotaciones en el código Java. Estos validadores requiere obligatoriamente el atributo “message” aun y cuando se especifique el atributo “key”. El parámetro “message” es utilizado como mensaje por defecto si es que la “key” no puede ser ubicada en el archivo de recursos. Adicionalmente, las expresiones OGNL están disponibles para las anotaciones. @Validation Se puede ubicar a nivel de método o a nivel de setter de una propiedad. Es una anotación que se utiliza sin parámetros. Solía ser obligatoria, pero ya no es necesario. @Validations Se aplica a nivel de método y permite agrupar las validaciones. Los grupos disponibles son: requiredFields requiredStrings intRangeFields stringLengthFields regexFields emails urls dateRangeFields expressions fieldExpressions customValidators visitorFields

Esta anotación no es específica por método. Esto significa que todas las validaciones son ejecutadas para todos los métodos de la clase Action. Ejemplo:

Page 42: 0.1 JPA.docx

@SkipValidation Esta anotación sirve para marcar los métodos que deben ser excluídos de la validación. @RequiredFieldValidator Es equivalente al validador “required”. Es obligatorio el ingreso del atributo “message” aun y cuando se haya colocado un valor al atributo “key”. @IntRangeFieldValidator Funciona de la misma forma que el validador “int” utilizado en XML. Soporta los valores de “max” y “min”. Otros validadores El comportamiento es similar a los validadores usados en XML. La documentación del framework porporciona mayor detalle: @DoubleRangeFieldValidator @EmailValidator @UrlValidator @DateRangeFieldValidator @StringRegexValidator @ExpressionValidator @FieldExpressionValidator @ConversionErrorFieldValidator @VisitorFieldValidator

Resumen

Recordar que Struts 2 es un framework bastante potente que permite agregar funcionalidad de tipo Ajax mediante la incorporación de algunos “tags” proporcionados por algún plug-in que trabaje con librerías de JavaScript como por ejemplo Dojo o JQuery.

También, Struts 2 proporciona mecanismos para “bloquear” el envío duplicado de formularios de captura de datos mediante el empleo del tag <s:token>.

Struts 2 permite definir validaciones para los campos de captura de los formularios.

Si desea profundizar estos temas, puede consultar las siguientes páginas. http://struts.apache.org/2.2.1/docs/ajax-tags.html Aquí hallará la lista completa de tags Ajax en Struts 2 y ejemplos de uso. http://code.google.com/p/struts2-jquery/ En esta página, hallará el plug-in de jQuery para Struts 2 así como la documentación y ejemplos propocionados por Google Code. http://dojotoolkit.org/ En esta página, hallará documentación sobre el framework Dojo Toolkit. http://jquery.com/ En esta página, hallará documentación sobre el framework JavaScript JQuery.

Page 43: 0.1 JPA.docx

JAVA PERSISTENCE API (JPA)TEMA 2: OR-MAPPING CON JPA

2.1 ANOTACIONES Las anotaciones pueden clasificarse en dos grupos:

Anotaciones lógicas describen el modelo de entidades desde el punto de vista del modelamiento orientado a objetos. Constituyen una especie de metadata del modelo. Anotaciones físicas están relacionadas con el modelo en la base de datos (modelo físico) y tienen que ver con tablas, columnas, etc.

Las anotaciones dentro de una clase Java se pueden colocar a nivel de atributos o a nivel de métodos. Si se colocan a nivel de atributos se denomina “ Field Access” mientras que si se coloca a nivel de métodos se denomina “Property Access”.

Es equivalente a:

En la especificación de JPA 2.0 se introduce la anotación @Access permite combinar los dos modos presentados en el ejemplo. Esta anotación permite sobre escribir el modo de acceso por defecto, aunque no es muy usual hacerlo.

Para definir una entidad basta con emplear la anotación @Entity y la anotación @Id.

Page 44: 0.1 JPA.docx

Anotación @Table Por defecto no es necesario incluir ninguna anotación para referenciar a una tabla. JPA asume que la tabla se llama igual que la clase Java en donde se define la entidad.

Sin embargo, si se desea especificar un nombre de tabla en particular para asociarlo con la entidad, es preciso utilizar la anotación @Table con el parámetro “name” respectivo.

Se puede indicar además el esquema de base de datos con el atributo “schema” (para aquellos motores de base de datos que lo soporten):

Se debe tener cuidado con el uso de mayúsculas y minúsculas, pues muchos manejadores de bases de datos no son sensibles a esto.

Anotación @Basic Cuando se “persiste” una propiedad de una entidad, el “persistente provider” verifica que el tipo de dato corresponda a un tipo soportado y trata de pasarlo hacia la base de datos vía el driver JDBC. Los tipos de datos soportados son:

Tipos primitivos byte, int, short, long, boolean, char, float doublé

Clases que encapsulan Byte, Integer, Short, Long, Boolean, Character, Float, Doublea tipos primitivos

Arreglos de bytes y caracteres byte[], Byte[], char[], Character[]

El esquema de una base de datos (en inglés, database schema) describe la estructura de una base de datos, en un lenguaje formal soportado por un sistema de gestión de base de datos (DBMS). En una base de datos relacional, el esquema define sus tablas, sus campos en cada tabla y las relaciones entre cada campo y cada tabla.

Page 45: 0.1 JPA.docx

Números java.math.BigInteger, java.math.BigDecimal

Cadenas de caracteres java.lang.String

Tipos de datos que manejan java.util.Date, java.util.Calendarfechas Java

Tipos de datos que manejan java.sql.Date, java.sql.Time, java.sql.Timestampfecha JDBC

Tipos enumerados Cualquiera

Objetos serializables Cualquiera

Se debe tener cuidado con el comportamiento del driver JDBC cuando los tipos de datos no coinciden entre lo que se define en la entidad y lo que soporta la base de datos, pues el driver intentará ejecutar la mejor conversión posible.

La anotación @Basic (que es opcional) se utiliza para indicar de forma explícita que dicho atributo debe ser almacenado en la base de datos.

Anotación @Transient Se emplea para marcar aquellos atributos de la entidad que NO deben ser guardados en la base de datos.

Anotación @Column Es una anotación de tipo físico, pues indica las características físicas de la columna en la base de datos.

Si no se especifica para un atributo determinado marcado como persistente, JPA asume que la columna se llama igual que dicho atributo. En cambio, si la columna tiene un nombre diferente, se deberá especificar con el uso de la anotación @Column.

Page 46: 0.1 JPA.docx

Los elementos que acompañan a la anotación @Column son:

Ejemplo 1:

Ejemplo 2:

Anotación @Lob Para el manejo de objetos binarios (imágenes o archivos generalmente) se requieren accesos especiales en el driver JDBC para efectuar conversiones entre el objeto Java y la columna en la tabla de la base de datos.

La anotación @Lob sirve para indicar que el atributo de dicha entidad requiere efectuar las conversiones vía JDBC.

Ahora bien, los campos LOB (acrónimo de Large Object) se pueden clasificar de dos maneras, siendo el manejo de cada manera un tanto diferente:

Page 47: 0.1 JPA.docx

En ambos casos, el driver JDBC es responsable de hacer las conversiones entre el objeto Java y la base de datos.

Ejemplo:

Anotación @Temporal Sirve para especificar tipos de datos basados en el tiempo. Estos tipos de datos se pueden clasificar en dos ramas: los que vienen del paquete java.sql y los que viene del paquete java.util.

En el paquete java.sql los tipos se trabajan directamente: java.sql.Date java.sql.Time java.sql.Timestamp

En cambio, en el paquete java.util: java.util.Date java.util.Calendar

Page 48: 0.1 JPA.docx

Se debe especificar la anotación @Temporal y además especificar el atributo “TemporalType” con uno de los tres valores que representan a cada uno de los tipos java.sql (DATE, TIME o TIMESTAMP).

Ejemplo:

2.2 MANEJO DE LA LLAVE PRIMARIA Cada Entidad debe tener una llave primaria. La anotación empleada es @Id sobre el atributo que contiene la llave. Adicionalmente se puede usar @Column para asociar al atributo con la columna en la tabla.

Una llave primaria se asume que es “insertable”, pero no puede ser “nullable” o “updatable” por lo que se debe tener cuidado de no sobre escribir esos atributos salvo excepciones muy específicas (cuando se manejan relaciones).

Los tipos de datos soportados para una llave primaria son:

2.3 GENERACION DE LA LLAVE PRIMARIA También se conoce como “Generación del ID” y se realiza mediante la anotación @GeneratedValue. En base a dicha anotación, el “Persistence Provider” genera el ID para cada entidad, y lo inserta en la columna respectiva.

Se debe tener en cuenta que dependiendo de la estrategia de generación del ID, el valor obtenido puede que no esté disponible hasta que se ejecute un “flush” o un “commit” a la transacción.

Existen cuatro estrategias posibles (que son un tipo enumerado de “GenerationType”): AUTO TABLE SEQUENCE IDENTITY

Page 49: 0.1 JPA.docx

ESTRATEGIA “GenerationType.AUTO” Este tipo de estrategia delega en el “Persistence Provider” la selección de la mejor forma de generación de los “ID”. Cualquiera sea la forma elegida por el provider, se confiará en los recursos de la base de datos para la obtención de los ID’s.

En el caso particular de EclipseLink con MySQL, la estrategia AUTO emplea una tabla denominada “sequence”.

Ejemplo:

ESTRATEGIA “GenerationType.TABLE” Esta estrategia es la más flexible y portable, pues permite que la aplicación genere ID’s diferentes de acuerdo a las necesidades.

La tabla requiere de dos columnas, una conteniendo el identificador para generar la secuencia y la otra columna contiene el último valor generado. Cada fila de la tabla es un generador diferente para los ID’s. Un ejemplo sencillo es el siguiente:

Page 50: 0.1 JPA.docx

Dado que no se ha especificado el nombre de un “generador” ni el nombre de una tabla, el Persistence provider seleccionará sus propios valores. Lo más común es que busque (la tabla debe existir en la base de datos) una tabla como la indicada en la figura.

¿Qué sucede si se desea especificar una tabla en particular? Se debe emplear la anotación @TableGenerator.

Ejemplo:

El atributo “allocationSize” indica el incremento en la generación del ID (para el caso del ejemplo va de uno en uno). Por defecto el incremento es 50.

ESTRATEGIA “GenerationType.SEQUENCE” Esta estrategia depende de las capacidades de la base de datos para manejar objetos de tipo “secuencia” (caso de Oracle).

Al igual que en la estrategia TABLE, basta con escribir la anotación para que el “Persistence Provider” seleccione la mejor secuencia dentro de la base de datos.

Ejemplo:

Page 51: 0.1 JPA.docx

Si se desea especificar una secuencia en particular, debe indicarse el “generator” y la anotación @SequenceGenerator. Se debe considerar que la secuencia debe existir previamente en la base de datos (salvo que la opción de generación de DDL esté habilitada en nuestra aplicación).

Ejemplo (la secuencia es para Oracle):

ESTRATEGIA “GenerationType.IDENTITY” Esta estrategia aprovecha las facilidades de la bases de datos para utilizar columnas de tipo “autoincremento”. Sin embargo es menos eficiente porque el identificador generado no está disponible hasta después que ocurra el INSERT.

No requiere una anotación para el “generador” dado que el campo autoincremental es parte de la definición de la tabla que corresponde a la entidad.

Ejemplo:

Page 52: 0.1 JPA.docx

2.4 LLAVE PRIMARIA COMPUESTA En algunas situaciones, en donde se requiere que la llave primaria de una entidad esté compuesta de múltiples atributos.

JPA proporciona dos formas de soportar esta necesidad mediante las anotaciones: @IdClass @EmbeddedId

Se debe tener en cuenta que: A. En ambos casos se requiere de una clase Java externa que sea la que maneje los atributos de la llave

primaria. B. La clase Java que maneja los atributos de la llave primaria, debe implementar los métodos equals() y

hashCode() con el fin que el Persistence Manager pueda almacenar e identificar las entidades. C. La clase Java que representa a la llave primaria debe ser pública, implementar a la interface Serializable

y tener un constructor sin argumento.

Ejemplo: Dada la siguiente tabla “tbmatricula” con una llave primaria compuesta:

La Entidad y la clase Java que maneja la llave primaria pueden representarse así (no olvidar que se debe generar los métodos getter/setter en ambas clases Java):

Page 53: 0.1 JPA.docx

Observe que la anotación @IdClass especifica el nombre de la clase Java que maneja la llave primaria

Observe también que la clase Java que maneja la llave primaria no posee anotaciones. Sin embargo, debe implementar los métodos nombrados líneas arriba:

El método equals() lo que hace es comparar uno a uno los atributos de la llave primaria contra los atributos de otra entidad para verificar que no se trate de la misma entidad.

El método hashCode() lo que hace es devolver un código “hash” de los valores de la llave primaria.

Page 54: 0.1 JPA.docx

Para consultar una entidad con una llave primaria compuesta sólo se requiere generar una instancia de la clase que maneja la llave primaria, cargarle los valores necesarios y pasar dicha variable al EntityManager.

Ejemplo:

2.5 OBJETOS EMBEBIDOS Un objeto embebido es aquel que es dependiente de una entidad: no tiene identidad por sí mismo. Entender este concepto es muy útil para el manejo de relaciones entre entidades.

Si bien, a nivel de Java, los objetos embebidos se administran de forma separada, a nivel de base de datos, la entidad y la clase embebida se almacenan sobre el mismo registro de la tabla.

Por ejemplo, en el siguiente gráfico se tiene la entidad “CUSTOMER” y la tabla “tbcustomer”. Observe que los datos de la dirección pueden constituir una clase separada:

Page 55: 0.1 JPA.docx

Si se convierte la dirección en una clase “Embebida” quedaría así:

Se debe observar que: a) La Entidad declara un atributo con el tipo de dato de la clase “Address” y a este atributo le coloca la

anotación “@Embedded” para indicar que esa clase es “embebida”. b) La clase “Address” NO tiene anotaciones que indiquen que es una entidad. Únicamente tiene la

anotación “@Embeddable” para indicar que hay “otra” clase que la incluye (o que la referencia). c) Ambas clases tienen sus getter/setter. d) Ambas clases deben definirse en el archivo persistente.xml. e) Finalmente, es importante saber que sólo se puede ejecutar quienes sobre la clase marcada como

“Entidad”.

ResumenUna clase Java se convierte en Entidad al agregar la anotación @Entity. Además, existen otras anotaciones que permiten el mapeo contra columnas de la tabla en la base de datos.

Existen cuatro maneras de generar la secuencias para ID’s: AUTO TABLE SEQUENCE IDENTITY

Recordar el uso de la anotación @Temporal para tipos de datos que manejan tiempo.

Page 56: 0.1 JPA.docx

Tema 3: Relaciones entre entidades

3.1 CONCEPTOS BÁSICOS

ROLES Las relaciones entre entidades tienen tres diferentes perspectivas:

a) La primera es el punto de vista desde un lado de la relación. b) La segunda en el punto de vista desde el otro lado de la relación. c) La tercera es la perspectiva global que mira ambos lados de la relación.

Estos “lados” son conocidos como “roles”. Tal es así que en cada relación hay dos entidades que se relacionan mutuamente de tal manera que cada una cumple un rol dentro de la relación. Es más, una entidad puede jugar muchos roles dentro de un modelo.

DIRECCIONALIDAD Existen maneras de crear, remover y actualizar las relaciones para darles mantenimiento. Si una entidad tiene relación con otra, existirá un atributo que sirve para identificar la relación y referirse a la entidad relacionada identificando así el rol que juega en la relación.

Cuando las entidades se referencian mutuamente se dice que la relación es bi-direccional. Ejemplo: El empleado sabe en qué Proyecto trabaja y el Proyecto conoce quiénes son sus miembros (las flechas indican el sentido de la dirección).

Si una entidad apunta únicamente a otra, la relación es unidireccional. El empleado conoce su Dirección, pero la inversa no necesariamente es cierta (la flecha indica el sentido de la relación).

Ahora bien, la relación Bi-direccional puede ser descompuesta en dos relaciones uni-direccionales. Cada relación tendrá un origen (“source” o rol de referencia) y un destino (“target” o rol referido). Se debe tener en cuenta esto, pues el origen y destino varían según la perspectiva que estemos usando para analizar la relación.

CARDINALIDAD La cardinalidad de una relación sirve para determinar cuántas instancias de una entidad existen en cada lado de una misma relación.

Cada rol dentro de la relación tendrá su propia cardinalidad, la cual indicará cuando exista una sola o muchas instancias.

Por ejemplo, muchos empleados pueden trabajar en el mismo departamento (se muestra una relación de muchos a uno):

Page 57: 0.1 JPA.docx

ORDINALIDAD Un rol puede especificarse de forma más detallada para indicar si puede o no estar presente en una relación. La ordinalidad sirve para indicar si la entidad “target” necesita ser especificada cuando la entidad “source” es creada.

Debido a que la ordinalidad es un valor lógico (verdadero o falso) es más práctico referirse a ella como “opcionalidad” de la relación.

MAPEANDO LA RELACIÓN ENTRE ENTIDADES

Existen básicamente dos formas de asociación: Las basadas en valores simples. Las basadas en colecciones de valores.

Dentro de esas formas de asociación, existen cuatro formas de “mapeo”: Relación One-To-One (valores simples) Relación Many-To-One (valores simples) Relación One-To-Many (colecciones de valores) Relación Many-To-Many (colecciones de valores)

A nivel de Base de Datos, la relación entre entidades significa que una tabla referencia a otra tabla: aparece el concepto de “Foreign Key” para indicar aquellos campos de una tabla que hacen referencia a la “Primary Key” de otra tabla.

A nivel de JPA las columnas que forman la “Foreign Key” se conocen como “Join Columns” y emplean la anotación @JoinColumn para indicar dicha funcionalidad.

3.2 RELACIÓN MANY-TO-ONE Es la relación más típica que podemos encontrar en el mundo real. En UML se requiere que la clase “source” tenga un atributo del tipo de la clase “target” para poder navegar hacia ella.

Ejemplo: Si varios Empleados pueden trabajar en un Departamento, la relación de entidades se puede modelar como se muestra a continuación:

Page 58: 0.1 JPA.docx

Tenga en cuenta que: a) La clase “source” tienen un atributo que corresponde al tipo de la clase “target” (observe el atributo

“departamento”). b) A dicho atributo se le debe colocar la anotación @ManyToOne.

Ahora falta llevar la relación al modelo de base de datos siguiente:

Las tablas físicas están relacionadas mediante la columna “DPTO_ID” en la tabla “tbempleado” que apunta a la columna “DEPT_ID” en la tabla “tbdepartamento”. Entonces, la “Join Column” de la relación es la columna “DPTO_ID”.

El lado que tiene a la “Join Column” se conoce como el “OWNER SIDE” de la relación, mientras que el lado que no tiene a la “Join Column” se conoce como “INVERSE SIDE”. En este ejemplo, el lado OWNER es la tabla “tbempleado” y el lado INVERSO es la tabla “tbdepartamento”.

La anotación @JoinColumn siempre se debe colocar en el lado “OWNER” de la relación. La entidad “Employee” debe quedar así (observe la anotación @JoinColumn):

Page 59: 0.1 JPA.docx

Si no se coloca la anotación @JoinColumn, JPA asume el nombre por defecto, el cual está formado por el nombre del atributo en la entidad owner seguido de un guión bajo (“_”) y concatenado con el nombre de la columna PK en la tabla inversa.

3.3 RELACIÓN ONE-TO-ONE La relación “Uno a Uno” es casi igual a la relación “Muchos a Uno” con la sola excepción que una instancia de la entidad “source” puede apuntar a una única instancia de la entidad “target”. Estrictamente hablando, eso significa que la entidad “target” no puede ser compartida por otras instancias de la entidad “source”.

A nivel de base de datos esta relación implica un criterio de “unicidad” o llave única en la “Foreign Key” de la entidad “source”.

Page 60: 0.1 JPA.docx

Obviamente se requiere definir la relación en la Entidad “Employee”: para ello se hace uso de la anotación @OneToOne y también se requiere usar @JoinColumn (en este caso, la columna de Join es “PARKING_ID”). La entidad “Employee” quedará así:

3.4 BIDIRECCIONALIDAD DE LA RELACIÓN ONE-TO-ONE En algunas situaciones se requiere considerar la relación inversa entre las entidades, también conocida como bidireccionalidad de la relación. La decisión es un criterio de modelamiento, más no una obligación a nivel de programación.

Para lograr esto, se requiere que la entidad “target” tenga un atributo de la clase correspondiente a la entidad “source”. Dicho atributo debe tener la anotación @OneToOne con el elemento “mappedBy”

Page 61: 0.1 JPA.docx

que indique cual es el atributo de la clase “source” que contiene la relación y apunta a la entidad “target”.

Ejemplo: en el caso de la entidad “ParkingSpace” (“es el “target” de la relación) se tendría el siguiente atributo:

Debe tenerse en cuenta dos reglas:a) La anotación @JoinColumn se coloca en la entidad que mapea a la tabla que contiene la columna de

join (o a la entidad que es “owner” de la relación). b) El elemento “mappedBy” debe colocarse a la anotación @OneToOne de la entidad “inversa” o “target”

de la relación. 3.5 RELACIÓN ONE-TO-MANY Cuando una entidad se asocia con una “colección” de otras entidades estamos ante una relación de “uno a muchos”. En el ejemplo del Empleado vs. el Departamento, la relación es bidireccional por naturaleza. En una relación bidireccional, siempre existen dos “mapeos”: uno por cada relación. A nivel de base de datos, la tablas siguen siendo las mismas.

Y a nivel de entidades, la entidad “Employee” es la misma.

Como se tiene que implementar el lado inverso de la relación entre Empleado y Departamento, se debe modificar la entidad “Department” para agregar la relación inversa “One-To-Many”: se debe “mapear” una colección de entidades “Empleado” usando la anotación @OneToMany. Adicionalmente, como éste es el lado inverso de la relación, se debe usar el atributo “mappedBy” para indicar cuál es el atributo dentro de la entidad “Employee” que contiene la llave de la relación:

Page 62: 0.1 JPA.docx

NOTA: En este caso se está usando una colección indicado el tipo de los elementos que almacena dicha colección: Collection<Type>. Esto genera una dependencia al compilar por lo que no es recomendable.

La otra forma de colocar la relación es especificando el atributo “targetEntity” sin especificar el tipo de dato contenido en la colección:

Esquemáticamente las dos relaciones se ven así:

Page 63: 0.1 JPA.docx

Es importante tener en cuenta que: a) El lado “many-to-one” siempre es el lado “owner” de la relación. En consecuencia, la anotación

@JoinColumn debe estar en dicho lado. b) El lado “one-to-many” es el lado “inverso”, por lo que el elemento “mappedBy” debe ser utilizado en

este lado. c) Si no se especifica el “mappedBy”, JPA considera que es una relación unidireccional de tipo one-to-

many por lo que requiere el uso de una tabla de Join. Tener en cuenta que esto puede ocasionar errores al desarrollar aplicaciones.

3.6 RELACIÓN MANY-TO-MANY Cuando una o más entidades se asocian con una “colección” de otras entidades y dichas entidades tienen relaciones sobrepuestas con las mismas entidades “target”, se dice que estamos frente a una relación de tipo “Mucho-a-Muchos”.

Por ejemplo: Un “Empleado” pueden trabajar en múltiples “Proyectos” y cada “Proyecto” puede tener a muchos “Empleados”.

De los ejemplos anteriores podemos manejar las siguientes entidades:

Page 64: 0.1 JPA.docx

La relación “Muchos-a-Muchos” se puede expresar en las dos entidades (“source” y “target”) utilizando la anotación @ManyToMany, teniendo en cuenta que:

a) Cuando la relación “Many-To-Many” es bidireccional, ambos lados de la relación deben tener la anotación @ManyToMany.

b) No existen columnas de join en cada lado de la relación: la única forma de implementar ésta relación es utilizando una tabla de join, por lo que no existe manera de determinar CUAL es el lado “owner” de la relación, en consecuencia, se debe asumir que uno de los lados es el “owner”.

c) Al igual que en las relaciones bidireccionales anteriormente tratadas, el lado que no sea “owner” debe utilizar el “mapeddBy”, en caso se omita éste elemento, JPA deducirá que se trata de dos relaciones unidireccionales separadas.

En el ejemplo, la anotación @ManyToMany debe colocarse en ambas entidades:

Page 65: 0.1 JPA.docx

El modelo de base de datos es:

A nivel de base de datos, una “Join Table” consiste simplemente de dos “Foreign Key” o columnas de join que referencian (cada una) a un lado de la relación. La anotación @JoinTable se usa para configurar la tabla de join de la relación:

a) Cada columna de Join se distingue dependiendo del papel dentro de la relación: lado owner o lado inverso.

b) La columna de Join que pertenece al lado “owner” se describe usando el elemento “joinColumns”. c) La columna de Join que pertenece al lado “inverse” se describe usando el elemento

“inverseJoinColumns”.

En el ejemplo, falta indicar la JoinTable de la siguiente forma (asumiendo que Employee es el owner de la relación).

Tenga en cuenta que el elemento “name” dentro de @JoinColumn especifica el nombre de la columna en la tabla de Join, mientras que el elemento “referencedColumnName” indica la columna que es “Primary Key” en la tabla que se encuentra al extremo de la relación ( sea owner o inversa). Y en el lado inverso de la relación se pone el elemento “mappedBy”:

Page 66: 0.1 JPA.docx

3.7 OPCIONES DE FETCH Las entidades y sus atributos pueden ser cargados de dos formas:

LAZY: Cuando se cargan de forma “perezosa”, es decir, se cargan en el momento en que se requieren. EAGER: Cuando se cargan de forma “proactiva”, es decir, al momento de cargar la entidad “owner” de la relación.

En términos de JPA, se usa el elemento “fetch” acompañando a la anotación de la relación e indicando el valor de FetchType.LAZY o FetchType.EAGER. En una relación de valores simples el FetchType por defecto es EAGER. En una relación de colecciones de valores, el FetchType por defecto es LAZY. En una relación bidireccional, el FetchType puede ser EAGER en un sentido y LAZY en el otro dependiendo del tipo de navegación que se desea.

Tema 4: Lenguaje de Consultas JPQLJPA soporta dos formas para expresar consultas que recuperan entidades desde una base de datos:

El lenguaje de consultas (queries), conocido como Java Persistence Query language ( JPQL ), es un lenguaje independiente del manejador de base de datos que trabaja con entidades en lugar de usar tablas. La API de criterios, que sirve para construir consultas basadas en objetos Java en lugar de escribir los queries en strings.

4.1 INTRODUCCIÓN A JPQL Los antecedentes de JPQL se pueden encontrar en la especificación de EJB 2.0 con el lenguaje EJB-QL en el cual se introdujo una forma de navegar entre los Beans y sus relaciones, así como filtros y funciones agregadas. Los queries operan dentro de una unidad de persistencia y pertenecen a una de las siguientes clasificaciones:

a) SELECT, son queries que recuperan una o más entidades, filtrando los resultados si fuera necesario.

b) AGGREGATE, los queries de este tipo son variaciones de los queries del tipo SELECT, con la salvedad que agrupan resultados para producir información sumarizada (de ahí la necesidad de usar la cláusula GROUP BY ).

Page 67: 0.1 JPA.docx

c) UPDATE, son queries que se emplean para actualizar un conjunto de entidades.

d) DELETE, son queries que se utilizan para remover un conjunto de entidades.

Al utilizar los queries se debe considerar que las entidades son referenciadas por su nombre. Si una entidad no tiene asignado un nombre de forma explícita, JPA asume el nombre de la clase como nombre por defecto: este nombre se conoce como “abstract schema name” de la entidad dentro del contexto del query.

También, es importante resaltar que para los queries es indiferente el uso de mayúsculas y minúsculas salvo en dos casos: nombre de entidades y nombres de atributos de cada entidad.

Dada una entidad como la siguiente ( entidad “Employee” ):

El query más sencillo que se pueden ejecutar es:

Page 68: 0.1 JPA.docx

Observe que la notación es muy similar al SQL normal, pero con ligeras diferencias:

a) En JPQL, lo que sigue a la cláusula “FROM” es el nombre de la entidad, es decir, no se coloca el nombre de la tabla (recordar que la Entidad “mapea” a una tabla).

b) En JPQL, es obligatorio que las entidades sean “calificadas” con un “alias”: en el caso del ejemplo, el alias es “e”. Este “alias” se conoce como “variable de identificación”.

c) El alias indicará que el resultado será uno o más entidades del tipo correspondiente a la entidad.

d) El tipo de resultado de un Query no puede ser una Colección. Debe ser un tipo simple o una Entidad.

A partir del uso del “alias” para la entidad, se puede utilizar la notación “dot” (el punto “.”) para referenciar campos persistentes de la entidad. Por ejemplo, si queremos seleccionar únicamente los nombres de los empleados sería así:

En este caso, como el campo “nombre” es un String, el resultado del query devolverá uno o más Strings. De la misma forma puede trabajarse para cualquier otro atributo, sea una lista, colección o campos simple.

El seleccionar algunos campos de la entidad (al igual que en SQL) recibe el nombre de “proyección”. Se debe tener en cuenta su uso si es que se van a descartar (no usar) varios atributos de la entidad al momento de generar reportes (dada la sobrecarga que se genera en el framework JPA ).

En el siguiente ejemplo, se puede seleccionar una entidad que no está en la cláusula FROM:

Observe que “departamento” es una campo de la entidad “Employee”, pero a la vez es una Entidad (dada la relación establecida @ManyToOne). Por tanto, el resultado de ese query será una entidad “Department” obtenida a partir de la relación.

FILTROS Al igual que en SQL, se puede filtrar los resultados a obtener utilizando la cláusula WHERE y la notación “dot”.

JPQL incluye operadores como IN, LIKE y BETWEEN, funciones como SUBSTRING y LENGTH además de soportar subqueries.

Ejemplo:

En este ejemplo, el filtro lo constituye el atributo “nombre” de la entidad “Department” que está vinculada con la entidad “Employee”.

Page 69: 0.1 JPA.docx

JOIN ENTRE ENTIDADES Al igual que en SQL, si se desea navegar entre las relaciones de las entidades y retornar elementos de la colección, se debe ejecutar un JOIN entre entidades. Se puede ejecutar el JOIN al más puro estilo del tradicional SQL indicando los criterios de JOIN en la cláusula WHERE. Sin embargo, JPQL proporciona la facilidad de especificar el JOIN dentro de la cláusula FROM con la finalidad de expresar el JOIN en términos de la relación existente entre las entidades: JPA se encargará de armar la sentencia SQL equivalente. Un JOIN ocurre si se cumple cualquiera de las siguientes condiciones en el SELECT: 1) Dos o más declaraciones de variables son listadas en la cláusula FROM y aparecen en la cláusula SELECT.

2) El operador JOIN es empleado para extender a una variable de identificación usando “expression path”.

3) Un “path expression” en cualquier parte del query navega a través de un campo de asociación en la misma o en otra entidad.

4) Una o más condiciones WHERE comparan atributos de variables de identificación diferentes.

Se debe tener en cuenta que ante la ausencia de condiciones de JOIN entre entitades, se generará un producto cartesiano entre la primera entidad y cada ocurrencia de la segunda entidad. INNER JOIN Un “inner join” entre dos entidades se puede especificar de cualquiera de la maneras indicadas anteriormente. Sin embargo, la forma preferida es mediante el uso del operador JOIN en la cláusula FROM. La sintaxis básica es: [INNER] JOIN <path_expression> [AS] <identifier>

Ejemplo 1: se asume que “phones” contiene una relación JPA entre “Employee” y “Phone”

Ejemplo 2: múltiples Joins ( los joins se interpretan de izquierda a derecha desde el FROM)

OUTER JOIN Un “outter join” entre dos entidades produce un ámbito en el cual solo un lado de la relación es requerido para completar el resultado. Por ejemplo, un outer join entre “Empleado” y “Departamento” mostrará todos los empleados y los departamentos a los que han sido asignados, pero con la salvedad que el “Departamento” será retornado únicamente si existe dentro de la relación ( a diferencia de un inner join ). Su sintaxis es la siguiente: LEFT [OUTER] JOIN <path_expression> [AS] <identifier> Ejemplo 1:

Page 70: 0.1 JPA.docx

FETCH JOIN Este tipo de Join sirve para ayudar a los programadores a optimizar los accesos a la base de datos. Permite que los queries especifiquen una o más relaciones que deben ser navegadas y pre-cargadas por el mecanismo de recuperación de datos de tal forma que no se ejecuten “lazy load” en tiempo de ejecución. En otras palabras, reduce la cantidad de accesos a la base de datos.

Ejemplo:

QUERIES AGREGADOS La sintaxis es muy similar a SQL: se requiere el uso del agrupamiento con GROUP BY Es opcional el uso del filtro mediante la cláusula HAVING. JPA incluye cinco funciones agregadas: AVG : Promedio aritmético.

COUNT : Cantidad de repeticiones.

MIN: Menor valor.

MAX: Mayor valor.

SUM: Suma de valores

Ejemplo:

En este ejemplo se obtienen todos los departamentos, la cantidad de empleados de cada departamento, el sueldo máximo y el sueldo promedio teniendo en consideración sólo aquellos departamentos que tengan más de 5 empleados. QUERIES Existen dos formas para definir “queries” en JP-QL: La primera forma es definirlo dinámicamente en tiempo de ejecución como una cadena de caracteres que se construye de acuerdo al flujo de la aplicación. Esto implica compilar el “query” cada vez.

La segunda forma es definir el “query” vía anotación o XML y referenciarlo por el nombre cada vez que se requiera (algo similar a IBATIS). A diferencia de la forma anterior, los “queries nombrados” son estáticos, pero son mucho más eficientes para ser ejecutados.

4.2 CONSULTAS DINÁMICAS Un query se puede definir de forma dinámica simplemente pasando una cadena de caracteres con la sentencia JPQL al método createQuery() del EntityManager. Ahora bien, se puede indicar el resultado esperado o se puede omitir y de esta forma tendremos un query sin tipo definido ( “unTyped query” ).

Page 71: 0.1 JPA.docx

Para aquellas aplicaciones que utilizan muchos queries, se debe considerar el costo de “compilar” la sentencia JPQL: 1) Se ejecuta un “parse” de la cadena JPQL en un árbol de sintaxis para verificar que esté correctamente escrito.

2) Para cada entidad dentro de la expresión se obtiene la metadata.

3) Se genera la sentencia SQL equivalente.

Se debe tener en consideración (al igual que en JDBC) las implicancias de concatenar un query y luego pasarlo al EntityManager para evitar la inyección de código SQL malicioso. Por ello es preferible usar parámetros. Tambien, para aquellos queries empleados con mayor frecuencia, es preferible usar los queries nombrados ( NamedQueries ). Un ejemplo con TypeQuery:

Un ejemplo con Query :

Page 72: 0.1 JPA.docx

4.3 CONSULTAS NOMBRADAS Este tipo de query sirve para organizar y mejorar el desempeño de una aplicación. Se define empleado la anotación @NamedQuery, la cual se coloca dentro de la definición de una Entidad: la anotación define no solamente el nombre del query sino tambien la sentencia JPQL en sí. Se recomienda escribir los queries de manera ordenada de tal forma que ayuden a la visibilidad y lectura de los mismos dentro de la definición de la entidad. El nombre del query ( atributo “name” ) debe ser único dentro de toda la unidad de persistencia. Si se hace caso omiso a esta restricción, los resultados pueden ser imprevisibles en tiempo de ejecución. Se puede definir múltiples queries nombrados empleando la anotación @NamedQueries, la cual es un arreglo que acepta varias anotaciones @NamedQuery. Ejemplo: El mismo query del ejemplo anterior, pero ahora definido en la clase Order.java

Se invoca así:

Page 73: 0.1 JPA.docx

Si deseamos definir varios NamedQueries en la entidad, se tendría que hacer así:

Y se puede invocar así:

Page 74: 0.1 JPA.docx

4.4 USO DE PARÁMETROS Los parámetros enviados a un “query” permiten la reutilización de sentencias de forma tal que las consultas ejecutadas con diferentes parámetros en cada invocación, retornen diferentes resultados. Es preferible enviar parámetros a las consultas en lugar de estar construyendo una nueva cadena de caracteres por cada invocación, pues así se evita compilar repetidas veces los “queries”. PARÁMETROS NOMBRADOS Se utilizan cuando dentro de la sentencia JPQL, los parámetros van precedidos por el símbolo de “:” seguido del nombre del parámetro. Al momento de ejecutar el query, el programador debe especificar el nombre del parámetro (empleando el método setParameter ) y el valor a ser cargado para reemplazarlo dentro de la sentencia JPQL. Los parámetros nombrados proporcionan claridad al código de la sentencia JPQL ( cuando se utilizan nombres adecuados), por lo que son preferidos respecto a los parámetros ordinales. Ejemplo usando parámetros nombrados:

Page 75: 0.1 JPA.docx

PARÁMETROS ORDINALES Se utilizan cuando dentro de la sentencia JPQL, los parámetros van precedidos por el símbolo de “?” seguido del número del parámetro. Al momento de ejecutar el query, el programador debe especificar el número del parámetro y el valor a ser cargado para reemplazarlo dentro de la sentencia JPQL. Ejemplo con parámetros ordinales:

4.5 EJECUCIÓN DE QUERIES JPA proporciona tres formas de ejecutar queries: a) Para queries que retornan un único valor se aplica el método getSingleResult().

b) Para queries que retornan una lista de valores se aplica el método getResultList(). c) Para queries que ejecutan sentencias de delete/update se aplica el método executeUpdate(). Se debe tener presente que: a) Por defecto, los queries devuelven listas desordenadas.

b) Cuando se aplica el método getResultList(), el tipo de dato retornado es una Collection (si no hay resultados, se devuelve una Collection vacía ). Sin embargo, la variable Java que recibe los resultados debe ser de tipo List. Ejemplo:

Page 76: 0.1 JPA.docx

c) Cuando se aplica el método getSingleResult(), si no existen resultados se devuelve la excepción NoResultException ( la aplicación deberá controlar la excepción). La ocurrencia de ésta excepción no genera un rollback de la transacción en curso.

d) Cuando se aplica el método getSingleResult(), si existen muchos resultados (en lugar de uno) se devuelve la excepción NoUniqueResultException ( la aplicación deberá controlar la excepción). La ocurrencia de ésta excepción no genera un rollback de la transacción en curso.

e) Cualquier query de tipo SELECT puede especificar además el uso de modos de bloqueo para los registros seleccionados con el fin de no impactar en el base de datos los indicadores de rendimiento. Esto se ejecuta vía el método setLockMode().

4.6 SINTAXIS DE JPQL

Page 77: 0.1 JPA.docx
Page 78: 0.1 JPA.docx
Page 79: 0.1 JPA.docx
Page 80: 0.1 JPA.docx
Page 81: 0.1 JPA.docx
Page 82: 0.1 JPA.docx

JAVA SERVER FACES ( JSF )

1.1 INTRODUCCION A JSF Java Server Faces (JSF) es el estándar “oficial” en la capa web para la plataforma Java EE. JSF incluye un conjunto de componentes predefinidos para la interfaz gráfica web (UI ), un modelo de programación basado en eventos y la habilidad para añadir componentes desarrollados por terceros.

El objetivo de la tecnología Java Server Faces ( JSF ) es construir aplicaciones web de forma similar a como se construyen aplicaciones standalone con Java Swing, AWT (Abstract Window Toolkit), SWT (Standard Widget Toolkit) o cualquier otra API similar.

JSF fue creado mediante el trabajo de la organización JCP ( Java Community Process ) mediante la especificación JSR 127 iniciada a mediados del año 2001 y finalizada en Marzo del 2004. Su principal objetivo es facilitar el desarrollo de interfaces gráficas para las aplicaciones web por medio de los siguientes caminos:

Proporciona un desarrollo basado en componentes, independientes del cliente. De esta manera se incrementa la productividad del desarrollador. Simplifica el acceso y administración de los datos capturados o enviados a la interfaz de usuario. Maneja de forma automática el estado de la interfaz de usuario entre múltiples peticiones HTTP. Proporciona un “framework” amigable mediante el uso de patrones de arquitectura para las aplicaciones web.

En resumen, toma los mejores elementos de los frameworks que le precedieron (CGI, Servlet, JSP, Struts, Spring MVC ) y los combina en un conjunto de API’s estándares para el desarrollo de interfaces de usuario.

La versión actual es JSF 2.0 y está soportada por las siguientes especificaciones: JSR 127 : Java Server Faces ( http://www.jcp.org/en/jsr/detail?id=127 ) JSR 252: Java Server Faces 1.2 ( http://www.jcp.org/en/jsr/detail?id=252 ) JSR 276: Design-Time Metadata for JavaServer Faces Components (http://www.jcp.org/en/jsr/detail?id=276 ) JSR 314: Java Server Faces 2.0 (http://www.jcp.org/en/jsr/detail?id=314 )

Al ser JSF una especificación, se pueden encontrar implementaciones de diferentes fabricantes, lo cual permite no vincularse con ningún proveedor en particular y tener la total libertad de seleccionar aquel que más se acomode a nuestras necesidades.

Algunas implementaciones de JSF 2.0 son: Proyecto Mojarra ( La implementación de referencia de SUN Microsystems ahora propiedad de Oracle

Corp.). Se puede consultar en el siguiente enlace: https://javaserverfaces.dev.java.net/ Oracle ADF Faces, que extiende la funcionalidad de JSF proporcionando muchas funcionalidades Ajax. MyFaces (Fundación Apache http://myfaces.apache.org/ ). Rich Faces, alojado por Jboss (Grupo RedHat) en el siguiente enlace: http://jboss.org/richfaces . ICE Faces, que contiene diversos componentes para interfaces de usuario más enriquecidas. Se puede

obtener información en el enlace: http://www.icefaces.org/main/home/ . jQuery4jsf que contiene componentes basados en el Framework JavaScript jQuery. Es un proyecto

alojado por Google Code en el siguiente enlace: http://code.google.com/p/jquery4jsf/

Page 83: 0.1 JPA.docx

1.2 ARQUITECTURA DE JSF

Los objetivos de diseño de JSF y la manera en que los cumple se aprecian en el cuadro siguiente:

Objetivo de diseño Forma de implementaciónObjetivo 1.Crear un framework estándar de componentes UI que pueda ser potenciado por herramientas de desarrollo y que a su vez permita crear UI de alta calidad u manejar la incorporación de dichas UI’s a la aplicación.

JSF proporciona una API basada en componentes que se pueden usar para ensamblar aplicaciones Web.

Los componentes UI estándar proporcionados por la especificación, están acompañados de “tag libraries” de tipo “core” y “html” (con funcionamiento muy similar a JSTL)

Objetivo 2.Definir un conjunto ligero de clases java para los componentes UI, el estado de los componentes y el manejo de eventos.Objetivo 3.Proporcionar un conjunto común de componentes UI incluyendo los elementos estándares para formularios HTML. Dichos componentes deben poder servir para definir nuevos componentes.Objetivo 4.Proporcionar un modelo de JavaBeans para controlar los eventos en el lado cliente y conectarlos a las aplicaciones.

JSF proporciona un mecanismo de fácil empleo mediante el cual los componentes UI en el lado web están débilmente acoplados (mediante un Lenguaje de expresiones similares a JSTL) a los POJO’s del servidor (conocidos como “Managed beans”)

Los “managed Beans” se declaran en el archivo faces-config.xml o se usan anotaciones.

El control de la conversación se realiza en el “JSF request process Lifecycle”.

Objetivo 5. Definir API’s para validación de datos de entrada.

EL JSF request process lifecycle también permite manejar las validaciones y conversiones dependiendo de los eventos que ocurren en la aplicación.

JSF permite construir validaciones personalizadas.

Page 84: 0.1 JPA.docx

Objetivo 6.Especificar un modelo para el manejo de i18N en los componentes UI.

JSF proporciona el manejo de “resource bundles” así como de localización (L10N). los componentes UI automáticamente reconocen estas características una vez que el “bundle” ha sido configurado.

Objetivo 7.Proporcionar una generación automática del formato apropiado de salida hacia un cliente determinado.

JSF proporciona API’s bastante flexibles basadas en tecnologías de “rendering” que pueden ser “enchufadas” bajo demanda. Por ejemplo, si el cliente es un iPhone el “render” de la página será HTML específico para dicho equipo. Objetivo 8.

Soporta accesibilidad

JSF confía plenamente en las tecnologías existentes de Java EE. Eso significa que una aplicación JSF es básicamente una aplicación desarrollada bajo los estándares Java EE con algunas configuraciones específicas:

Configuración #1: Dentro del “deployment descriptor” (archivo web.xml ) de la aplicación, se debe registrar el servlet controlador ( llamado “Faces Controller” ). Tener en cuenta que en algunos contenedores web como GlassFish v3 no se requiere el archivo web.xml.

En caso que el archivo web.xml no exista o no se encuentre, el “Faces Controller” mapea los urls siguientes de forma automática: /faces/* *.jsf *.faces

También se puede agregar los siguientes “mappings” en el web.xml:

Page 85: 0.1 JPA.docx

Configuración #2: Opcionalmente se puede tener un archivo de configuración de JSF llamado faces.config.xml el cual está ubicado al mismo nivel que el web.xml

El archivo contiene la configuración de todos los elementos de una aplicación JSF, aunque también pueden emplearse “anotaciones” en el código java para evitar el uso de éste archivo. Un ejemplo del contenido del archivo faces-config.xml es:

Configuración #3: Si se está ejecutando la aplicación en un contenedor web que no soporta a JSF, las librerías del framework deben colocarse en el folder “lib” de la aplicación:

Page 86: 0.1 JPA.docx

La construcción de páginas se realiza con “Facelets XHTML” empleando para ello “tag libraries”. Se puede declarar las librerías usando “XML namespaces” o usando la forma tradicional:

En resumen, una aplicación JSF es como cualquier aplicación web que incluye los siguientes elementos: Las páginas web. Las librerías de etiquetas (o tags ) para insertar componentes UI a las páginas. Un conjunto de “backed beans”, que son componentes que definen las propiedades y funcionalidad de

los componentes de UI. Archivos de configuración para el modelo navigacional (aunque es opcional).

o El indispensable archivo descriptor web.xml o Archivos desarrollados por los programadores: convertidores, validadores, listeners.

Opcionalmente algunas etiquetas personalizadas para objetos UI personalizados.

1.3 CICLO DE VIDA DE UN REQUEST El ciclo de vida de una petición JSF es la secuencia de eventos que suceden cuando se hacen peticiones HTTP con una aplicación JSF (la interacción entre el navegador web y la aplicación). La primera vez que se ejecuta la petición, JSF crea un árbol de componentes UI en memoria. Para las siguientes peticiones el árbol es rápidamente construido de nuevo: si se capturan valores en un formulario, estos son procesados y validados. Si la validación es correcta, los valores capturados son cargados al modelo. Luego se procesan los eventos y se reportan los errores que pudieran ocurrir. Si todos los eventos han sido procesados y el modelo ha sido actualizado correctamente se envía una respuesta final (render) al cliente. El manejo del ciclo de vida de manera automática lleva un control de los cambios en los estados de tal forma que el cliente siempre refleje los cambios en el lado servidor.

El ciclo completo se muestra en el gráfico:

Page 87: 0.1 JPA.docx

Una explicación detallada del ciclo:

FASE 1: Restore View El concepto de “Faces View” es la representación en el lado servidor (a manera de espejo) de la interfaz de usuario que se muestra en el navegador.

En esta fase se restaura una “vista” existente de alguna transacción anterior o se genera una nueva en función a la petición HTTP entrante.

Si la petición es nueva, se genera una “vista” que se almacena en un objeto conocido como “Faces Context”, el cual sirve como almacenamiento para los datos de la petición http durante el manejo del ciclo de vida. La vista generada sigue una estructura de árbol como la siguiente:

FASE 2: Apply Request Values En esta fase se ejecuta todo el trabajo de procesar los pares de datos (conocidos como “value-pair parameters”) que llegan en el request desde la página mostrada en el lado cliente: el parámetro y su valor.

De esta manera, cada elemento del árbol que representa a la “Faces View” se carga con el valor respectivo como se muestra en el gráfico6:

Page 88: 0.1 JPA.docx

Se debe especificar que existen dos tipos de componentes UI: Aquellos que pueden aceptar valores: campos de texto, cajas de chequeo, etc. Aquellos que permiten ejecutar acciones: botones y enlaces.

Es bueno saber que se puede alterar el curso normal de las fases para casos especiales. Para ello se debe configurar el atributo “immediate” en un componente UI.

También es bueno especificar que existen 3 tipos de interfaces usadas: ValueHolder : implementada por todos los componentes UI que tienen el atributo “value” EditableValueHolder: implementada por todos los componentes UI de un formulario, que poseen

valores editables. ActionSource : implementada por los componentes que generan acciones.

FASE 3: Process ValidationsEn esta fase se ejecuta la conversión y validación de los datos recibidos. JSF invoca al método processValidators() en la instancia raíz de UIViewRoot el cual se propaga recursivamente hacia los componentes UI del árbol.Cuando cada método processValidators() de cada componente es invocado, se ejecutan las conversiones y/o validaciones especificadas.

Si ocurre algún error de conversión o validación, la propiedad “valid” se marca en “false” y se encola un objeto “FacesMessage” en el FacesContext. Estos objetos serán mostrados posteriormente en la vista del lado cliente.

FASE 4: Update Model Values En esta fase, los datos se promueven hacia un objeto Java conocido como “Managed Bean”.

Page 89: 0.1 JPA.docx

El mecanismo es similar a las fases anteriores: en la instancia UIViewRoot se ejecuta el método processUpdate() el cual se propaga en cascada. Sólo los componentes definidos como tipo UIInput pueden enviar datos a un objeto Managed Bean.

Al final la fase, todos los atributos del objeto “managed bean” tienen cargados los valores de la “Faces View” como se muestra en el gráfico:

FASE 5: Invoke Application Es en esta fase en la que cualquier código personalizado se puede ejecutar.

FASE 6 Render Response En esta fase se ejecutan métodos encodeXXX() para enviar el componente al cliente. Los encode los que hacen es seleccionar el mejor tipo de lenguaje de marcas apropiado para el cliente: HTML, WML, XML, etc.

Adicionalmente se graba el estado actual de la “Faces View” para que esté disponible en los subsiguientes requests.

Page 90: 0.1 JPA.docx

Java Server Faces permite además que se pueda codificar “phase listeners” para controlar la ejecución de código en algún punto exacto del ciclo de vida del request. Para ello se debe: implementar la interface PhaseListerner registrar la clase en el archivo faces-config.xml o usar anotaciones

1.4 FACELETS La tecnología denominada “Facelets View Declaration Language” (VDL) fue desarrollada como una extensión de JSF por Jacob Hookom e incorporada a la especificación JSF 2.0. El objetivo fue reemplazar el uso de JSP (aunque se mantiene el reconocimiento de los JSP por motivos de compatibilidad). Los Facelets permiten a los desarrolladores declarar componentes UI en diferentes tecnologías de presentación utilizando para ello plantillas (templates) HTML.

La meta de diseño principal fue permitir la composición de una vista a partir de diferentes páginas físicas separadas.

Algunos conceptos importantes en esta tecnología: a) Página (page): Se define así a la totalidad de la página web que es mostrada al usuario. Se asocia con

una viewId en el modelo de navegación. b) Fragmento de página (page fragment ): se generan y utilizan como si fueran páginas, siendo la principal

diferencia que los fragmentos no son páginas web completas sino que se emplean para “armar” páginas completas.

c) Página de Plantilla ( page template ): son formatos reutilizables que se emplean para construir páginas y/o fragmentos. Si existen porciones de página que son comunes en muchas páginas web, se pueden crear plantillas para dichas porciones.

d) Facet: son áreas dentro de la plantilla en donde el contenido puede ser agregado por los desarrolladores cuando generan las páginas. Los facets pueden tener un contenido por defecto.

En la tecnología JSP, los “templates” era codificados mediante el uso de: jsp:incluye <%@include %>

Page 91: 0.1 JPA.docx

En la tecnología JSTL se utilizaba <c:import />

Las páginas en Facelets se generan usando XHTML. La idea de usar XHTML es hacer portables a las páginas entre diversos ambientes de desarrollo.

Además, Facelets requiere el uso de “XML namespaces” para soportar las siguientes librerías de tags: JSF HTML Tag Library. JSF Core Tag Library. JSTL Core Tag Library. JSTL Functions Tag Library. JSF Facelets Tag Library.

El encabezado de la página debe ser similar a esto (dependiendo de las librerías a utilizar):

Las páginas en Facelets deben tener extensión .xhtml En el archivo web.xml de la aplicación debe configurarse los siguientes “context param”:

El primer parámetro define que la extensión “.xhtml” es el sufijo por defecto de todas las páginas que manejan contenido JSF.

El segundo parámetro indica que la implementación de JSF ignore los comentarios XML en las páginas Facelets. Una comparativa9 entre JSP y Facelets:

Page 92: 0.1 JPA.docx

Una gran característica de los Facelets (no disponible en JSP) es el poder generar “templates”. Un “template” es una página XHTML que emplea algunos tags de Facelets para definir varias “divisiones” lógicas de la vista como por ejemplo: cabecera, pie de página y contenido. La idea es tener partes reusables de código sin tener que repetir el mismo código en diferentes páginas.

Existen dos perspectivas para desarrollar “Templates”: Template File: es el archivo conteniendo la “plantilla” o estructura de composición (formato) a generar. El

contenido de este archivo está compuesto por: a. El contenido que debe ser mostrado a todos los clientes se escribe directamente en el archivo. b. El contenido que se puede reemplazar en cada archivo cliente se marca con el tag <ui:insert>. c. El “template” nunca debe ser accedido directamente por los clientes.

Template Cliente file: es el archivo que corresponde con una viewId. Emplea una o más páginas para generar el contenido basado en el Template File. Este archivo contiene:

a. La especificación del “template file” mediante el tag <ui:composition> b. La especificación del contenido a reemplazar con el tag <ui:define> (que se asocia al tag <ui:insert>

del “template file” ). Esquemáticamente se puede ver así:

Page 93: 0.1 JPA.docx

La tecnología de Facelets proporciona tags en la librería denominada “ui” cuyo namespace es http://java.sun.com/jsf/facelets :

Page 94: 0.1 JPA.docx
Page 95: 0.1 JPA.docx

Ejemplo de Template: Observe las primeras líneas de código y anote las declaraciones en el tag <html> : se declaran los

“namespaces” de las librerías. Observe los bloques con el tag <ui:insert>. Lo que está dentro del bloque es el valor por defecto de esa

zona ( si es que el viewID no reemplazara nada ). Observe la línea 9 para ver el uso de “resources folders”. En este caso, la aplicación busca un folder

“resources” y dentro de este, busca el nombre de la library que está como parámetro ( “css” ). Los tags <ui:include> permiten incoporar contenido que se encuentra en otros archivos, dentro del

template o de la viewId.

Page 96: 0.1 JPA.docx

Ejemplo de viewID o página cliente: Observe las declaraciones del tag <html> en la primeras líneas. En la línea 10 se declara el <ui:composition> para indicar cual es el archivo de “layout” con el que

trabaja ésta página. Los bloques <ui:define> sirven para reemplazar el contenido de cada bloque dentro de la zona de la

plantilla identificada con el mismo nombre. Tenga en cuenta que el contenido que se encuentre fuera de los tags <ui:composition> no aparecerá en

los clientes.

Ejemplo de tag <ui:decorate>:

En este caso se mostrará tanto el texto anterior como posterior al tag.

Page 97: 0.1 JPA.docx

1.5 MANAGED BEANS Al igual que el Framework Spring que proporciona la noción de “Inversión de Control (IoC), JSF tambien proporciona una robusta habilidad para ello con las facilidades de los “Managed Beans”. Una “Managed Bean” es una clase Java que representa información de un formulario web. Para ello hace uso de los POJO’s ( Plain Old Java Objects ), que son objetos que almacenan datos de la aplicación pero que no implementan o extienden ninguna interfaz o clase específica de algún Framework.

Un POJO declarado dentro de una aplicación JSF se convierte en un “Managed Bean” al cual nunca se le generará utilizando el método “new” de una clase Java. En lugar de ello, el contenedor JSF inicializará el objeto únicamente cuando la aplicación lo requiera ( Lazy initialized ).

Cualquier clase Java que siga las reglas de los Java Beans pueden ser registrado como una “Managed Bean”.

Debe tenerse en cuenta que hay dos maneras de configurar los “managed bean”: Usando anotaciones dentro del programa Java. Es la forma más recomendada pues permite un código

más cohesionado y fácil de mantener. Se emplea la anotación @ManagedBean antes de la definición de la clase (desde JSF 2.0).

Usando XML dentro del archivo faces-config.xml. Se emplea el tag <managed-bean> para efectuar la declaración.

Un “managed Bean” típicamente tiene 3 partes: a) Las propiedades del Bean : generalmente un getter y un setter por cada atributo. Los métodos setter

son invocados automáticamente por el JSF cuando el formulario web es enviado. b) Métodos para controlar acciones: Generalmente es sólo un método, pero podrían ser varios si es que

el formulario posee múltiples botones de envío. c) Un lugar para los datos resultantes: No es

invocado automáticamente por JSF. Debe ser llenado por el método controlador en base a los resultados de la lógica de negocio.

Un ejemplo de una aplicación sencilla JSF: Se presenta un formulario donde se debe ingresar un nombre y presionar el botón de “saludar”. La aplicación responde con una página de saludo.

Page 98: 0.1 JPA.docx

El “Managed Bean” es bastante sencillo:

Y la página de respuesta:

Page 99: 0.1 JPA.docx

Como se ve en el ejemplo, el “Managed Bean” está marcado para funcionar en el ámbito @SessionScoped. Sin embargo, los ámbitos pueden ser:

Page 100: 0.1 JPA.docx

1.6 LENGUAJE DE EXPRESIONES JSF El lenguaje de expresiones utilizado en JSF 1.0 y 1.1 era una extensión del JSP Standard Tag Library (JSTL). La principal extensión que se introdujo en EL con JSF y que no está presente en versiones anteriores es el concepto de “expresiones diferidas” ( deferred expresiones ).

En JSP, todas las expresiones que aparecen entre ${ … } se evalúan inmediatamente tan pronto como la página en “renderizada”.

JSF introduce el procesamiento del ciclo de vida del request que controla lo que sucede cuando se ejecuta un submit. Para ello, se introduce el concepto de “expresión diferida” para permitir que las expresiones sean utilizables tanto durante el rendering de la página como durante el submit.

Este concepto permite que una expresión entre símbolos #{ … } como por ejemplo #{usuario.nombre} sirva tanto para mostrar un valor al usuario como también para recibir el valor ingresado por el usuario.

El objetivo de tener un Lenguaje Unificado de Expresiones ( EL ) es proporcionar una manera fácil de acceder a los objetos desde cualquier punto de la aplicación. En general EL: Evita la necesidad de referir al objeto padre ( request, sesión o application). Evita usar directamente los métodos get/set del objeto. Permite navegar de forma arbitraria en la jerarquía de objetos JavaBeans (usando la notación .dot).

Por ejemplo:

Esta expresión es una forma abreviada de invocar al método “getFirstName()” de una Managed Bean llamado “userBean”: La primera parte ( en este caso “userBean”) es la “BASE” que indica el ámbito donde buscar. La segunda parte ( en este caso “firstName”) es la propiedad, la cual puede navegarse usando la notaicón .dot.

Una facilidad que brinda E.L. es la invocación directa a métodos públicos y no estáticos de los managed beans. Por ejemplo:

NOTA: Para que E.L. sea lo más simple posible, no está permitido el envío de parámetros a los métodos. JSF busca los objetos en un orden jerárquico comenzando por los objetos implícitos para luego buscar en los managed beans de la aplicación. El siguiente cuadro resume los objetos implícitos que pueden constituir la “BASE”:

Page 101: 0.1 JPA.docx

NOTA: 1) Las propiedades de los objetos que son de tipo Map se acceden usando:

#{ MapObject [´key´] }

Page 102: 0.1 JPA.docx

2) El objeto ”Flash” es un tipo de almacenamiento temporal que permite que los datos estén presentes en el siguiente request.

1.6.1. OPERADORES E.L. Además de los corchetes ( para Map) y del punto ( . ) existen otros operadores como se muestra en la tabla siguiente:

1.7 BACKING BEANS Para implementar los backing beans en JSF, se debe crear una clase Java por cada página JSF y registrar dicha clase como una managed bean. Lo usual es que la clase Java se llame igual que la página. Se recomienda que los backing beans se declaren en el ámbito del “request”. En general, los backing beans se encargarán de armar toda la “tubería” necesaria entre la página y el modelo, porque: Contienen las propiedades correspondientes a los campos de entrada del formulario. Contienen “action methods” y “action listener” que corresponden a los componentes UI. Contienen declaraciones de instancias de componentes UI que se vinculan a los componentes UI utilizados en la página.

ResumenJSF es una especificación, por tanto tiene varias implementaciones de diversos fabricantes.

Básicamente tiene 4 librerías: core, html, user interface y composite que pueden ser complementadas con librerías de otros fabricantes.

El lenguaje de expresiones requiere la sintaxis: #{ … } y permite la referencia a propiedades de “managed beans” como también a métodos.

JSF tiene dos formas de navegación: la implícita y la explícita ( que requiere el uso del archivo faces-config.xml )

JSF permite el empleo de “plantillas” mediante el uso de los tags d ela librería “ui”.

Puede profundizar los conceptos tratados en el libro: “The Complete Reference : Java Server Faces 2.0” Capítulos 1, 2, 3, 4 y 5

Si desea investigar más acerca de estos temas, puede consultar las siguientes páginas. http://www.mkyong.com/jsf2/jsf-2-templating-with-facelets-example/ Aquí hallará un ejemplo del uso de Facelets.

Page 103: 0.1 JPA.docx

http://www.mkyong.com/jsf2/jsf-2-0-hello-world-example/ En esta página, hallará un ejemplo básico de JSF.

TEMA 2: COMPONENTES DE INTERFAZ DE USUARIO. 2.1 INTRODUCCIÓN Los componentes UI Java Server Faces son elementos configurables y reutilizables que componen la interfaz de usuario de las aplicaciones Java Server Faces. Un componente se define como una pieza de software con reglas de uso bien definidas que permitan que pueda ser utilizado por otros componentes. Un componente de interfaz de usuario ( UI Component ) es un tipo específico de componente que muestra contenido que puede ser modificado por el usuario a lo largo del tiempo. Este contenido puede ir desde un simple campo de ingreso de datos o botones, hasta elementos más complejos como árboles o datagrids. La tecnología Java Server Faces proporciona un conjunto de clases de componentes UI, que especifican toda la funcionalidad del componente, cómo mantener su estado, mantener una referencia a objetos del modelo, y dirigir el manejo de eventos y su representación para un conjunto de componentes estándar. Estos componentes son completamente extensibles, lo que significa que podemos extenderlas para crear nuestros propios componentes personalizados. Es más, la tecnología JSF es tan flexible que proporciona una arquitectura de componentes que incluye: Un conjunto de clases UIComponent para especificar el estado y comportamiento de componentes UI. Un modelo de representación (“rendering”) que define cómo representar los componentes de diferentes formas. Un modelo de conversión que define cómo conectar conversores de datos a un componente. Un modelo de validación que define cómo registrar validadores con un componente. Un modelo de eventos (“events”) y oyentes ( “listeners”) que define cómo manejar los eventos de los componentes.

Todas las clases de componentes UI de Java Server Faces descienden de la clase UIComponentBase, que define el estado y el comportamiento por defecto de un UIComponent. Las clases auxiliares como Renderer, tag Handlers, Validador, Converter, etc técnicamente no son Componentes UI porque no colaboran en la representación visual del componente. Los Componentes UI además tienen un conjunto de archivos como imágenes, hojas de estilo y JavaScripts que generalmente son responsables de la apariencia y comportamiento de componente dentro de una página web. La especificación JSF se refiere a dichos archivos como “recursos”.

Page 104: 0.1 JPA.docx

2.2 ARQUITECTURA DE COMPONENTES UI Los componentes UI se pueden clasificar en dos tipos: Aquellos que inician una acción como por ejemplo los botones. Aquellos que proporcionan datos como los campos de ingreso.

En JSF, los componentes se pueden ubicar en una de las dos clasificaciones mencionadas en base a las interfaces que implementan según la especificación JSF (para el primer caso es la interface ActionSource2 y para el segundo caso es la interface ValueHolder o la interface EditableValueHolder). La razón para el uso de interfaces es utilizar la más alta abstracción posible con el fin de encapsular las capacidades de todos los componentes UI. De esta manera es mucho más fácil entender todos los componentes JSF simplemente comprendiendo las interfaces que se implementan. Se debe indicar que los componentes, además de las interfaces mencionadas, pueden implementar otras interfaces para definir un comportamiento particular. El siguiente cuadro resume esta clasificación:

Page 105: 0.1 JPA.docx

La jerarquía de clases de los componentes11 dentro del paquete javax.faces.component es la siguiente (donde la flecha continua significa “herencia” y la discontinua significa “implementación”):

Page 106: 0.1 JPA.docx

Si bien ésta jerarquía “encapsula” al componente, no describe la forma en que dicho componente será mostrado al usuario.

Un ejemplo de algunos componentes UI: UICommand: Representa un control que dispara actions cuando se activa. UIForm: Encapsula un grupo de controles que envían datos de la aplicación. Este componente es similar a la etiqueta HTML <form> . UIGraphic: Muestra una imagen. UIInput: Toma datos de entrada del usuario. Esta clase es una subclase de UIOutput. UIOutput: Muestra la salida de datos en un página. UIPanel: Muestra una tabla. UISelectItem: Representa un sólo ítem de un conjunto de ítems. UISelectItems: Representa un conjunto completo de ítems. UISelectBoolean: Permite a un usuario seleccionar un valor booleano en un control.Esta clase es una subclase de UIInput.

Page 107: 0.1 JPA.docx

UISelectMany: Permite al usuario seleccionar varios ítems de un grupo de ítems. Esta clase es una subclase de UIInput. UISelectOne: Permite al usuario seleccionar un ítem de un grupo de ítems. Esta clase es una subclase de UIInput.

Además, JSF proporciona un conjunto de componentes UI para HTML que facilitan el desarrollo de aplicaciones web específicamente para clientes HTML ( navegadores ). Dicho conjunto de componentes reside en el paquete javax.faces.component.html y derivan de la misma jerarquía de clases mostrada, con la característica específica de trabajar para clientes HTML. Normalmente el desarrollador no trabajará con los componentes directamente sino que aprovechará las características proporcionadas por el “Renderer” de JSF: un Renderer es una clase responsable de tomar una instancia del UIComponent y generar la salida a ser mostrada según las características específicas del cliente. Como se mencionó en el tema del ciclo de vida de un request JSF, el árbol de componentes UI (que se conoce como “Vista”) es manejado por el ViewHandler. Sin embargo, el StateManager se encarga de preservar el árbol de componentes entre los subsiguientes requests. Para ello, se guarda el estado completo de los componentes utilizando un mecanismo especificado en el web.xml de la aplicación:

Los parámetros a colocarse pueden ser : server: significa que el estado de la aplicación debe almacenarse en el servidor entre cada request. Este es el comportamiento por defecto, por lo que no es necesario colocarlo en el web.xml. client: significa que el estado de la aplicación se almacena en el cliente. Se almacena como una marca dentro de la página de forma tal que aparezca escondida y sea enviada como un campo oculto ( tipo “hidden” ).

La librería de componentes estándares está compuesta por cuatro librerías: La librería CORE: se asocia al namespace “f:” y proporciona utilidades para validación, conversión, internacionalización, etc. La librería core no es específica para clientes HTML dado que ninguno de sus componentes tiene una representación visual en el lado cliente. La librería HTML: se asocia al namespace “h:” y está diseñada específicamente para clientes HTML dado que proporciona un conjunto de objetos comunes a muchas aplicaciones web: botones, campos de texto, etc. La librería de tags para Plantillas FACELET: asociada al namespace “ui:” permite agregar funcionalidades de plantillas y formatos. Fue introducida en JSF 2.0.

La librería de tags para Componentes Compuestos: introducida también con JSF 2.0, se registra bajo el namespace “cc:” y agrega la habilidad para definir un “contrato de uso” con componentes compuestos. 2.3 LIBRERÍA CORE El namespace con el que se declara es http://java.sun.com/jsf/core y se le asigna el prefijo “f”. Se listan las principales funcionalidades de cada tag. Para el detalle de los atributos soportados, por favor consultar la documentación de JSF. Tag <f:actionListener>

Page 108: 0.1 JPA.docx

Permite al desarrollador registrar de forma declarativa una instancia de ActionListener sobre un Componente UI. Un ActionListener es un manejador de evento que responde a eventos que suceden en la página JSF.

Tag <f:ajax> Permite al desarrollador agregar de forma declarativa, comportamiento Ajax al componente asociado. Tag <f:attribute> Agrega un atributo con un nombre específico y un valor string a un componente dentro del tag si es que dicho componente no contiene un atributo con dicho nombre. Los valores se almacenan en un Map que es parte del componente de tal forma que los valores persisten cuando se administra el estado de dicho componente.

Tag <f:convertDateTime> Se utiliza para convertir valores String a valores java.util.Date.

Tag <f:convertNumber> Se utiliza para convertir valores String a valores java.lang.Number.

Este tag maneja una serie de patrones para formateo de los valores. Tag <f:converter> Este tag crea una instancia de la clase Java registrada con el ID especificado, la cual debe implementar a la interfaz javax.faces.convert.Converter. Luego, asocia esta instancia con el componente UI más cercano.

Page 109: 0.1 JPA.docx

Tag <f:event> Permite que el desarrollador registre de manera declarativa un ComponentSystemEventListener en un componente UI. Soporta dos atributos: listener: cuyo valor debe ser un “Method Expression” que se refiere a un método con la misma firma que el método “processEvent” de la interfaz ComponentSystemEventListener. type : especifica el nombre del evento. preRenderComponent preRenderView postAddToView preValidate postValidate

Ejemplo:

Tag <f:facet> Representa un componente anidado que mantiene una relación “especial” con el tag que lo encierra.

Tag <f:loadBundle> Este tag permite manejar el modelo de i18N especificando un recurso ( bundle ) para el “locale” de la vista actual. El contenido del “bunle” es cargado en un Map.

Tag <f:metadata> Este tag encapsula un conjunto de elementos que se utilizan para especificar la metadata para una vista Facelet. En consecuencia debe ser un tag hijo del tag f:view. En el siguiente ejemplo, se especifica que el valor del parámetro que viene en el request HTTP con el nombre “foo” será automáticamente recuperado y cargado dentro de la propiedad “bean.foo”.

Page 110: 0.1 JPA.docx

Tag <f:param> Se utiliza para sustituir parámetros cuando se emplea dentro de un tag <h:outputFormat> o para agregar valores “query-string” a un URL cuando se utiliza dentro de <h:commandLink> o <h:outputLink> Tag <f:phaseListener> Sirve para registrar una instancia de PhaseListener sobre el UIViewRoot en donde se encuentra anidado el tag. Tag <f:selectItem> Agrega un componente hijo de tipo UISelectItem al componente UIComponent más cercano. Ejemplo:

Tag <f:selectItems> Este tag ubica al componente padre UIComponent más cercano y crea un nuevo UISelectItems vinculándolo a dicho componente padre.

Ejemplo 1: “ColoresMap” es un mapa (Map) a partir del cual se carga un listado de colores.

Ejemplo 2: Ahora la lista de colores se toma desde una Collection.

Page 111: 0.1 JPA.docx

Tag <f:setPropertyActionListener> Este tag permite colocar un valor directamente en un atributo de un backing bean. Ejemplo:

Tag <f:subview> Sirve para crear una subvista. Es útil con JSP pero no tiene mayor trascendencia en facelets. Sirve como contenedor para todos los componentes UIComponents usados dentro de una página anidada que se incluye vía <jsp:include> o vía JSTL con <c:import>. Ejemplo:

Page 112: 0.1 JPA.docx

Tag <f:validateBean> Este tag se integra al JSR 303 que especifica el “Bean Validation API”. El uso de este tag causada que una instancia de javax.faces.validator.BeanValidator se registre en el componente padre.

Ejemplo:

Tag <f:validateDoubleRange> Sirve para generar validaciones sobre el componente padre. Soporta atributos de máximo y mínimo. Ejemplo:

Tag <f:validateLength> Sirve para generar validaciones sobre Strings en el componente padre. Soporta atributos de máximo y mínimo. Ejemplo:

Tag <f:validateLongRange>Sirve para generar validaciones sobre el componente padre. Soporta atributos de máximo y mínimo. Ejemplo:

Tag <f:validateRegex> Este tag crea una instancia de javax.faces.RegularExpression y la asocia al componente padre para efectuar las validaciones. Ejemplo:

Page 113: 0.1 JPA.docx

Tag <f:validateRequired> Este tag genera una instancia de javax.faces.Required y lo asocia al componente padre. La funcionalidad es la misma que si se configura el atributo “required” en “true” para un componente editable. Ejemplo:

Tag <f:validator> Genera un validador y lo asocia al componente padre. Ejemplo:

Tag <f:valueChangeListener> Registra un Listener asociado a la instancia del component padre. Ejemplo:

Tag <f:verbatim> Este component es útil para JSP, pero no tiene mayor propósito con JSF Faceleters. Crea y registra una instancia hija de UIOutput en el componente asociado más cercano. Sirve para anidar contenido en HTML, XML o cualquier otro lenguaje de marcas. Ejemplo:

Page 114: 0.1 JPA.docx

Tag <f:view> Sirve para crear una vista. La vista sirve como contenedor para todos los componentes JSF utilizados en una página. Tag <f:viewParam> Permite que de forma declarative se registren parámetros como metadata asociada a la vista padre por lo que debe ser un componente hijo del tag <f:metadata>. El objetivo es soportar vistas “favoritas” que puedan ser invocadas via método GET. Ejemplo:

2.4 LIBRERÍA HTML El namespace con el que se declara es http://java.sun.com/jsf/html y se le asigna el prefijo “h”. Tag <h:body> Es el tag encargado de mostrar los códigos HTML <body> y </body> en una vista. Tag <h:head> Es el tag encargado de mostrar los códigos HTML <head> y </head> en una vista. Se utiliza para que JSF pueda incluir hojas de estilo y javascripts generados por los tags <h:outputScript> y <h:outputStylesheet>

Tag <h:form> Es el tag que muestra un formulario para captura de datos. Todos los tags que se encuentren en el interior serán enviados con el formulario. Configura un atributo “action” apuntando a un URL que define la acción a ejecutar y el atributo “method” configurado en “POST”.

Page 115: 0.1 JPA.docx

Tag <h:outputScript> Este tag muestra el tag HTML <script> con el atributo “src” determinado por los valores de “name” y “library” ingresados. La especificación de JSF 2.0 requiere que los recursos de la aplicación web sean colocados debajo del folder “resources”.

Tag <h:outputStyleSheet> Este tag muestra el tag HTML <link> con el atributo “href” determinado por los valores de “name” y “library” ingresados. Además, muestra el atributo “rel” con los valores de “stylesheet” y “text/css”.

Page 116: 0.1 JPA.docx

Tag <h:inputText> Muestra un campo de entrada de datos con el tag HTML <input> y el atributo “type” configurado en “text”.

Tag <h:inputTextarea> Muestra un campo de entrada de datos con múltiples líneas usando el tag HTML <textarea>.

Tag <h:inputSecret> Este tag muestra una caja de ingreso de datos del tipo “password”, es decir, los valores no se muestran al usuario.

Tag <h:inputHidden> Este tag genera un campo “oculto” dentro de la página. El componente no se visualiza al momento del “render” en el cliente.

Tag <h:outputLabel>

Page 117: 0.1 JPA.docx

Este componente muestra una etiqueta de texto usando el tag HTML <label> y puede de manera opcional, ser especificada para un campo de ingreso (con el atributo “for”).

Tag <h:outputLink> Este componente muestra un enlace usando el tag HTML <a> con el atributo “href” configurado con el valor del componente.

Si se desea enviar parámetros en el link se puede usar la forma siguiente:

Tag <h:outputFormat> Muestra un texto formateado. El texto se muestra dentro de un tag HTML <span> si es que se indica el atributo “id” o algún atributo de estilo.

Tag <h:outputText> Muestra el valor del componente como texto dentro de una página.

Page 118: 0.1 JPA.docx

Tag <h:commandButton> Este componente muestra un botón con el tag HTML <input> y el “type” configurado a “submit”, “reset” o “image”. Puede ser asociado a un “backing bean” o a un ActionListener para manejar eventos. La etiqueta del botón se especifica con el atributo “value” o con el “url” de la imagen. Adicionalmente soporta la obtención del texto desde un Bundle para efectos de manejar i18N. El tag emplea el método POST para enviar la data al servidor. El atributo “type” puede ser “submit” o “reset”. El atributo “action” se asocia a un método de algún backing bean.

Tag <h:button> Este component es similar a <h:link> y fue introducido en JSF 2 para permitir el soporte a vistas Facelets que puedan ser marcadas como favoritas (bookmarks). Se presenta un problema si los navegadores tiene el javaScript deshabilitado debido a que el tag genera un evento “onclick” para manejar la navegación vía “window.location.href”. Ejemplo:

Este código genera el siguiente HTML:

Tag <h:message> Este componente muestra los mensajes generados por JSF para el componente identificado por el atributo “for”.

Page 119: 0.1 JPA.docx

Tag <h:messages> Muestra todos los mensajes almacenados. Si el atributo “globalOnly” está en “true”, muestra los mensajes sin el identificador de componente. Utiliza celdas HTML de una tabla si es que se configura el atributo “layout” en “table”.

Tag <h:graphicImage> Este componente sirve para mostrar una imagen utilizando el tag HTML <img> con el valor del atributo “src” apuntando al valor del componente (value) o al atributo “url”. En JSF 2 se agregan los atributos “library” y “name” para soportar imágenes desde librerías de recursos.

Otra forma es usando el atributo “url”:

Page 120: 0.1 JPA.docx

Tag <h:selectOneListBox> Este componente muestra un <select> HTML cuyo tamaño de lista es igual a la cantidad de elementos <option>. Sólo permite la selección de un elemento.

Tag <h:selectOneMenu> Este componente muestra un <select> HTML cuyo atributo “name” es el ID del componente y el atributo “size” es 1. Cada opción del menú se muestra como un elemento <option>. Si la opción se marca como deshabilitada, se agrega el atributo “disabled”.

Tag <h:selectOneRadio> Este component muestra una table HTML con un conjunto de “radio buttons” entre los cuales el usuario puede escoger.

Page 121: 0.1 JPA.docx

Tag <h:selectBooleanCheckbox> Este component muestra un element HTML <input> de tipo “checkbox”.

Tag <h:selectManyCheckbox> Muestra una tabla con un conjunto de “checkboxes”

Page 122: 0.1 JPA.docx

Tag <h:selectManyListBox> Muestra un tag HTML de tipo <select> pero permitiendo selecciones múltiples.

Tag <h:selectManyMenu> Muestra un tag HTML de tipo <select> permitiendo selecciones múltiples. El tamaño de visualización es 1 (atributo “size”).

Este componente esta diseñado para situaciones en las que se necesita mostrar un menú de opciones al usuario para permitirle seleccionar múltiples opciones pero utilizando un menú que sólo muestra una opción a la vez. La principal diferencia entre los “select” y los “menus” en JSF es el atributo “size”. Los “menus” siempre tienen el “size” en 1 mientras que las listas pueden tener el tamaño variable. NOTA: Este componente no se visualiza correctamente en todos los navegadores. Tag <h:panelGrid> Es un contenedor tabular para otros componentes y es visualizado como una tabla HTML. Los componentes hijos son visualizados como celdas dentro de la tabla.

Page 123: 0.1 JPA.docx

Tag <h:panelGroup> Este componente crea un contenedor para agrupar a un conjunto de componentes bajo un padre. Al visualizar los componentes hijos, se usa el tag HTML <span>. Tag <h:dataTable> Este componente genera un contenedor tabular para otros componentes hijos. Tag <h:column> Este tag sirve como “hijo” del tag <h:dataTable>. 2.5 LIBRERÍA DE TEMPLATES El namespace con el que se declara es http://java.sun.com/jsf/facelets y se le asigna el prefijo “ui”. Sus tags han sido explicados en el tema de Facelets y Templates. 2.6 LIBRERÍA DE COMPONENTES COMPUESTOS El namespace con el que se declara es http://java.sun.com/jsf/composite y se le asigna el prefijo “composite”. Esta librería sólo se declara y utiliza en páginas que requieren el empleo de componentes compuestos JSF.

TEMA 3: CONVERSIONES, VALIDACIONES Y EVENTOS 3.1 INTRODUCCIÓN JSF proporciona componentes para manejar los aspectos de conversión y validación en el desarrollo de aplicaciones: Conversión: la realizan los “Converters” y garantiza que los datos sean del tipo esperado. Los converters implementan la interfaz javax.faces.convert.Converter. Validación: la realizan los “validators” para garantizar que los datos sean válidos en función a las restricciones de la aplicación. Los validators son implementaciones de la interfaz javax.faces.validator.Validator.

Es importante conocer que los “converters” al realizar una transformación de datos, requieren ser asociados tanto a componentes de entrada como de salida. Mientras que los “validators” sólo se asocian a componentes de entrada. Adicionalmente, JSF proporciona un sistema de mensajes que permite a los desarrolladores controlar la visualización de los mensajes de conversión y validación en las páginas, de una manera flexible utilizando uno o más tags de tipo <h:message> o <h:messages>. 3.2. EL SISTEMA DE CONVERSIÓN DE JSF En la fase denominada “Apply Request Value” es justamente donde se ejecuta la conversión de los valores que llegan desde el formulario hacia el tipo de dato apropiado. Si la conversión es exitosa, los valores pasan a ser validados. Todos los objetos que cumplan la función de “converters” deben implementar a la interfaz javax.faces.convert.Converter. Esta interfaz tiene dos métodos:

Page 124: 0.1 JPA.docx

Donde: El parámetro “context” es la instancia “FacesContext” del request. El parámetro “component” es el componente cuyo valor será convertido. El parámetro “value” es el valor a ser convertido.

El método getAsObject es invocado durante el procesamiento de entrada, para convertir los valores String que llegan en el request, al tipo de dato deseado.

El método getAsString es invocado durante la fase de salida para mostrar los valores en formato de String en cualquiera de las tecnologías de rendering que soporta el cliente. Si se lanza una excepción de tipo ConverterException, el componente se marca como inválido y se coloca un mensaje en el FacesContext. Los convertidores estándares son:

Page 125: 0.1 JPA.docx

Todos los “converters” se puede llamar usando el tag <f:converter> y especificando el ID, a excepción de DateTimeConverter y NumberConverter que tienen sus propios tags: <f:convertDateTime> y <f:convertNumber>. La forma implícita de conversión se realiza cuando JSF conoce el tipo de dato del valor. Por ejemplo, asumiendo que “age” es un atributo de tipo Integer del managed bean “user”, en el siguiente caso la conversión es implícita:

La forma explícita es cuando se usan los tres tags que proporciona la librería core de JSF. Tag #1: <f:convertDateTime>

Donde:

El “dateStyle” puede ser: short, médium, long, full o default. El valor de “type” puede ser: date, time o both (default). El valor de “binding” es una expresión que apunta a un método de una clase que implementa la interfaz javax.faces.convert.Converter.

Tag #2: <f:convertNumber>

Donde: “type” puede ser number, currency o percentage. “currencyCode” es el código ISO 4217 de las monedas. Por ejemplo, “USD” es para los dólares americanos y “EUR” para el euro. Para la moneda peruana se tiene el código “PEN”. “currencySymbol” se puede especificar para indicar el símbolo de la moneda a utilizar (pero se debe tener en cuenta que esto es válido con JDK 1.4 o superior). El atributo “currencyCode” toma preferencia sobre este. “groupingUsed” es un flag boolean que sirve para indicar cuando se debe usar un delimitador. El valor de “binding” es una expresión que apunta a un método de una clase que implementa la interfaz javax.faces.convert.Converter.

Page 126: 0.1 JPA.docx

Tag #3: <f:converter>

Donde: “converter-id” es el valor registrado en el archivo faces-config.xml de la aplicación. El valor de “binding” es una expresión que apunta a un método de una clase que implementa la interfaz javax.faces.convert.Converter.

Para vincular un Componente UI con un converter, simplemente hay que anidar el converter dentro del tag:

3.3 EL SISTEMA DE VALIDACIÓN DE JSF La interfaz javax.faces.validator.Validator es el núcleo del sistema de validaciones de JSF. Todos los objetos que cumplan la función de validadores deben implementar esta interfaz. Dicha interfaz tiene un único método:

Este método es invocado durante la fase de “Apply Request Values” si el componente está marcado como “Immediato” o durante la fase de “Process Validations” en caso contrario. Antes de invocar al método, JSF marca al componente como “inválido”. El método lanza la excepción ValidatorException si ocurre un error durante la validación: se almacena un mensaje en el FacesContext. En caso no ocurran errores, el componente recién se marca como “válido”´. A diferencia de los “converters”, los “validators” se registran por validator-id debido a que el concepto de validación no está asociado al tipo del objeto. Adicionalmente, JSF proporciona la facilidad de usar el atributo “required” en los tags. Si esta propiedad está presente, se ejecutan las validaciones. Los validadores estándares son:

Page 127: 0.1 JPA.docx

Para que JSF no valide campos que están vacíos se debe agregar lo siguiente al web.xml:

Los validadores se pueden asociar a los componentes UI de dos maneras: usando tags de la librería core o utilizando el MethodBinding. Usando los tags de la librería core: <f:validateDoubleRange>, <f:validateLongRange> y <f:validateLength>

Usando el MethodBinding:

Page 128: 0.1 JPA.docx

En este caso, se asocia a un método del managed bean “user”:

3.4 EL SISTEMA DE MENSAJES Los mensajes de error generados en la validación o en la conversión fluyen hacia el usuario mediante la clase javax.faces.application.FacesMessage, el contexto FacesContext y los componentes UIMessage y UIMessages. La clase FacesMessage encapsula los mensajes que describen los problemas de conversión y validación. Posee tres propiedades interesantes: severity : que puede ser INFO, WARN, ERROR, FATAL. summary: contiene los mensajes de forma comprensible para el usuario. detail: contiene los mensajes de forma comprensible para el usuario.

La instancia de FacesContext mantiene dos colecciones de instancias FacesMessage que pueden ser accedidas por diferentes formas del método getMessages(): Una de mensajes asociados con un componente. La otra de mensajes que no están asociados con el componente.

El método getMessages() de la instancia FacesContext: Sin argumentos retorna un Iterator de todos los mensajes (estén asociados o no con el componente). Con el argumento clientId retorna sólo los mensajes asociados con ese clientId. Si el clientId es NULL, retorna los mensajes que no están asociados con un valor específico de clientId.

3.4.1 ¿ EN QUE MOMENTO SE GENERAN LOS MENSAJES ? Existen tres momentos dentro del ciclo de vida del request cuando los componentes generan instancias de FacesMessage y las agregan al FacesContext: 1. Cuando falla una conversión. 2. Cuando falla una validación. 3. Cuando los datos, una vez convertidos y validados no pueden ser actualizados en el modelo durante la fase denominada “Update Model Values”.

En el caso de la conversión, un error significa el lanzamiento de la excepción ConverterException. La severidad de éste error siempre es ERROR. El converter tiene dos opciones: 1. No envía parámetros al ConverterException, en cuyo caso, se genera un FacesMessages con el mensaje “conversión failed”. 2. Se envía como parámetro una propiedad “message”, cuyo valor se utiliza como la propiedad “detail” de FacesMessage.

En el caso del validador, un error significa el lanzamiento de la excepción ValidatorException, el cual siempre envía un FacesMessage en su constructor. La severidad de la excepción siempre está a nivel de ERROR.

Page 129: 0.1 JPA.docx

En el caso de la actualización del modelo, cuando se lanza una excepción EL, se examina el mensaje de la excepción. Si no es null, se crea un FacesMessage con el mensaje como atributo “summary”. Si es null, se crea un FacesMessage con un mensaje de error genérico. 3.4.2 ¿ COMO SE AGREGAN LOS MENSAJES ? Se tiene que agregar al FacesContext

3.4.3 ¿ COMO SE VISUALIZAN LOS MENSAJES ? Existen dos componentes estándares que permiten visualizar los mensajes: UIMessages y UIMessage. En base a esos componentes, el kit de HTML tiene dos “renderers”: javax.faces.Messages y javax.faces.Message respectivamente, de manera tal que los tags a emplear son: <h:messages> y <h:message> que se encuentran en la librería html. a) Mostrando mensajes para un componente específico: al tag <h:message> se le debe proporcionar el atributo “for” para indicar el “componentId” acerca del cual se mostrarán los mensajes. De esta manera, el desarrollador puede colocar los mensajes en cualquier lugar de la página. b) Mostrando mensajes para todos los componentes: si se coloca el tag <h:messages> en algún lugar de la página, todos los mensajes que se encuentran en el FacesContext son mostrados a menos que se configure el atributo “globalOnly” (en cuyo caso sólo se muestran los mensajes que no están asociados a un determinado componente). Además, se puede especificar el atributo “layout” con los valores de “list” (los mensajes se muestran como una lista HTML sin orden alguno ) o “table” ( los mensajes se muestran como tabla HTML). c) Personalizando los mensajes: el contenido de los mensajes por defecto puede ser poco claro para efectos de una aplicación. Es posible proporcionar un “Resource Bundle” ( archivo .properties) con los mensajes que se desea manejar y de esa forma sobre escribir los mensajes por defecto de JSF.

Para ello se debe agregar el siguiente bloque al archivo faces-config.xml:

Page 130: 0.1 JPA.docx

Tener en cuenta que este archivo requiere que los tags vayan en cierto orden (debido al DTD). En este ejemplo se está indicando que el archivo de mensajes se llama “MyMessages.properties” y que los idiomas soportados son Español e Inglés. Además, se debe tener en cuenta que para sobre escribir los mensajes por defecto, el archivo de mensajes debe tener como “key” los messagesID del framework y como “value”, los textos que se desea para la aplicación. Algunos de los messageID estándares que pueden ser sobre escritos son: javax.faces.component.UIInput.CONVERSION javax.faces.component.UIInput.REQUIRED javax.faces.component.UISelectOne.INVALID javax.faces.component.UISelectMany.INVALID javax.faces.converter.BigDecimalConverter.DECIMAL javax.faces.converter.BigIntegerConverter.BIGINTEGER javax.faces.converter.BooleanConverter.BOOLEAN javax.faces.converter.ByteConverter.BYTE javax.faces.converter.CharacterConverter.CHARACTER javax.faces.converter.DateTimeConverter.DATE javax.faces.converter.DateTimeConverter.TIME javax.faces.converter.DateTimeConverter.DATETIME javax.faces.converter.DateTimeConverter.PATTERN_TYPE javax.faces.converter.DoubleConverter.DOUBLE javax.faces.converter.FloatConverter.FLOAT javax.faces.converter.IntegerConverter.INTEGER javax.faces.converter.LongConverter.LONG javax.faces.converter.NumberConverter.CURRENCY javax.faces.converter.NumberConverter.PERCENT javax.faces.converter.NumberConverter.NUMBER javax.faces.converter.NumberConverter.PATTERN javax.faces.converter.ShortConverter.SHORT javax.faces.converter.STRING javax.faces.validator.NOT_IN_RANGE javax.faces.validator.DoubleRangeValidator.MAXIMUM javax.faces.validator.DoubleRangeValidator.MINIMUM javax.faces.validator.DoubleRangeValidator.NOT_IN_RANGE javax.faces.validator.DoubleRangeValidator.TYPE javax.faces.validator.LengthValidator.MAXIMUM javax.faces.validator.LengthValidator.MINIMUM

Page 131: 0.1 JPA.docx

javax.faces.validator.LongRangeValidator.MAXIMUM javax.faces.validator.LongRangeValidator.MINIMUM

javax.faces.validator.LongRangeValidator.NOT_IN_RANGE javax.faces.validator.LongRangeValidator.TYPE Se puede editar el archivo “messages.properties” que se encuentra en el jar de las API’s de JSF y ver todas las llaves disponibles. 3.5 MODELO DE EVENTOS DE JSF JSF proporciona un modelo de programación basado en eventos que es muy similar al que se utiliza en el desarrollo de aplicaciones Swing o AWT. Esto permite un mejor control de interfaces de usuario complejas debido a que los componentes de dicha interfaz publican cambios en sus estados ( eventos) hacia un conjunto de objetos que actúan como “listeners” y que ejecutan las tareas requeridas. Hay dos tipos de eventos: Los eventos de aplicación Los eventos de ciclo de vida

Los eventos pueden ser publicados a lo largo del ciclo de vida de una aplicación JSF. Este ciclo de vida puede ser dividido en tres etapas: inicio (start-up).

Page 132: 0.1 JPA.docx

ejecución de procesamiento del ciclo de vida del request. La mayor parte del tiempo, la aplicación se ejecuta en esta etapa. finalización (shutdown).

Los eventos publicados durante la etapa de procesamiento del ciclo de vida de los request se muestra en el siguiente gráfico:

Los eventos que ocurren durante el start-up son: PostConstructApplicationEvent

Los eventos que ocurren durante el Shutdown son: PreDestroyApplicationEvent

Los eventos que ocurren en cualquier momento del ciclo de vida de la aplicación: ExceptionQueuedEvent PostConstructCustomScopeEvent PreDestroyCustomScopeEvent PostConstructViewMapEvent PreDestroyViewMapEvent PostAddToViewEvent PreRemoveFromViewEvent

3.5.1 EVENTOS DE APLICACIÓN

Page 133: 0.1 JPA.docx

En general, para manejar eventos Faces se puede escribir una clase “listener” que implemente la interfaz apropiada ( javax.faces.event.ActionListener ) y que se vincule al componente ( en este caso, al UIComponent). Para “Action Events” sin embargo, se puede escribir: o un método en una clase “Action” o un método en una clase “Listener”. La explicación es la siguiente: a) Un “action method” es un simple método Java que tiene lugar en un “managed bean”, no tiene argumentos y retorna un String. Estos “action methods” son manejados por un ActionListener, que por defecto toma el valor del String y lo envía al NavigationHandler con el fin de determinar el siguiente paso de navegación.

Un “action method” se asocia a un UIComponent con el atributo “action”. Ejemplo:

b) Si no se requiere navegación, se utilizan los “action listener method”, que es un método que simplemente se ejecuta y que no devuelve resultados ( retorna void). Se asocia a un UIComponent con el atributo “actionListener”.

Page 134: 0.1 JPA.docx

Los “Value Change Events” son eventos que se emplean para indicar que el valor de un componente UI ha cambiado. Generalmente se emplea para componentes que implementan las interfaces ValueHolder o EditableValueHolder.

Al igual que los “action events”, los “value change events” pueden manejarse de la misma manera.

Sin embargo, debe tenerse presente que el evento ocurre cuando se hace el submit del formulario. Es más, el evento sucede en la fase de “Process Validations”. Un siguiente envío del formulario sin alterar el valor, no genera que se dispare el evento debido a que no ha cambiado el valor del campo. Si se agrega el atributo “immediate” y se configura en “true”, se puede disparar el evento de cambio en la fase de ”Apply Request Values”. Para personalizar los Listeners se debe tener en cuenta que: Si se implementa la interfaz ActionListener se debe anidar dentro del componente UI el siguiente tag:

Page 135: 0.1 JPA.docx

Si se implementa la interfaz ValueChangeListener se debe anidar dentro del componente UI el siguiente tag:

3.5.2 EVENTOS DE FASE Los eventos de fase ( o “Phase Events” ) se procesan entre cada fase del procesamiento de ciclo de vida de un request. Se puede crear un Listener simplemente implementando la interfaz PhaseListener. Esta interfaz posee tres métodos que deben ser implementados: beforePhase() afterPhase() getPhaseId()

Los métodos beforePhase() y afterPhase() se ejecutan para todas las fases del ciclo de procesamiento de un request, por tanto, si se desea ejecutar alguna lógica especial en determinada fase, se deberá obtener el ID de la fase y en base a condiciones, controlar el flujo del código. El método getPhaseId() sirve para determinar a que fase está asociado el listener. Cuando se usa para cualquier fase retorna el valor ANY_PHASE:

Finalmente, el listener debe registrarse en el faces-config.xml :

3.5.3 EVENTOS DE SISTEMA Este tipo de eventos fueron introducidos con la especificación JSF 2.0 y proporcionan mayores detalles que los ofrecidos por los eventos de fase.

Page 136: 0.1 JPA.docx

TEMA 4: TÓPICOS AVANZADOS DE JSF I 4.1 JSF y AJAX JSF se constituye en el mejor framework que se integra y facilita el uso de las capacidades de Ajax. El concepto de AJAX corresponde a un conjunto de tecnologías ( Hojas de estilo, JavaScript, Document Object Model , etc. ) que permiten ejecutar llamadas asíncronas al servidor y procesar la respuesta modificando el árbol DOM que se almacena en el navegador. JSF proporciona dos maneras de trabajar con AJAX, la primera forma es mediante un tag nuevo identificado como <f:ajax> mediante el cual no hay que preocuparse acerca del uso de javaScript. La segunda forma es el uso de una API de JavaScript llamada jsf:ajax.request() que proporciona un puente estándar para las peticiones de tipo Ajax. 4.1.1 TAG <f:ajax> JSF proporciona un tag para el manejo de llamadas AJAX: <f:ajax>, que al igual que otros tags de la librería core, no puede ser empleado aisladamente. Es decir, debe ser anidado o debe contener a otros tags que se asocien con un Componente UI. Los atributos que acepta este tag pueden dividirse en dos:

Page 137: 0.1 JPA.docx

Por default, todos los componentes UI de captura de datos disparan el evento “valueChange”. Ejemplo:

4.1.2 JAVASCRIPT ESTÁNDAR Todas las implementaciones de JSF 2 deben contener una librería denominada “javax.faces” la cual contiene un Script llamado “jsf.js” que expone una serie de API’s estándares para ejecutar las invocaciones Ajax. Existen dos objetos principales dentro del javaScript: ajax y útil. El objeto “ajax” tiene las funciones siguientes:

Page 138: 0.1 JPA.docx

La función más importante es “request”, la cual toma tres parámetros: source : es el elemento DOM que dispara el requerimiento Ajax. Normalmente su valor es “this”. event: es opcional y corresponde al evento DOM que dispara el requerimiento Ajax. Se usa normalmente para recuperar información adicional sobre el evento ( por ejemplo que tecla fue presionada). options: también es opcional. Contiene una lista de llaves y valores según la relación siguiente:

execute : lista de ID’s (separadas por comas) a ser procesada durante el request. render : lista de ID’s (separadas por comas) a ser reemplazados durante el response. onevent : Función JavaScript a ser invocada para el evento. onerror : Función JavaScript a ser invocada si hay un error. params : parámetros a ser incluídos en el request.

Las opciones más importantes son “execute” y “render” y bajo JSF 2 permiten el concepto de “vista parcial”: es un mecanismo que permite que el procesamiento de ciclo de vida de un request se ejecute sobre uno o más componentes. Sólo los componentes identificados en el request sufren el proceso de validación, conversión y actualización del modelo. De igual forma, en el “render”, sólo los componentes indicados sufren la actualización en el árbol DOM sin tener que refrescar toda la página. Adicionalmente, en lugar de identificar cada uno de los componentes para el “execute” y el “render”, se puede emplear algunos “tokens”:

Para poder utilizarla la librería JavaScript es preciso incorporar en la página Faces el siguiente tag:

Este tag le dice a JSF que coloque el script en la cabecera de la página. Luego, al componente UI se le define el atributo correspondiente al evento que se desea manejar:

Page 139: 0.1 JPA.docx

En este caso se define el evento “onkeypress”: cada vez que se pulse una tecla, dicho valor aparecerá en el campo con id “outNombre”. 4.2. INTEGRACIÓN JSF + JPA Las entidades JPA también pueden funcionar como “Managed Beans” simplemente agregando las anotaciones @ManagedBean y la anotación de ámbito respectivo (por ejemplo @RequestScoped ). Es aconsejable emplear JSF 2 con EJB 3.0 y JPA para que el contenedor de EJB’s controle las transacciones. Sin embargo, se puede utilizar directamente JPA pero se debe tener en cuenta que hay que manejar la persistencia y las transacciones de forma manual. Enterprise Java Beans (EJB ) es una arquitectura de componentes Java en el lado servidor que permite el desarrollo rápido y simplificado de aplicaciones portables, distribuidas, transaccionales y seguras basadas en la plataforma Java EE.

Java PErsistence API (JPA) es un framework basado en Java que permite manejar datos relacionales en aplicaciones que emplean Java SE o Java EE.

En todo caso, si se emplea la tecnología de EJB 3.0, se requiere contar con un servidor de Aplicaciones como WebSphere de IBM, Oracle WebLogic o JBoss, dado que Apache Tomcat no soporta contenedores de EJB. Al igual que con Struts 2, se requiere el archivo persistence.xml dentro del folder META-INF y las librerías de la implementación de JPA ( para el curso es EclipseLink ). Un ejemplo de managed bean con JPA:

Page 140: 0.1 JPA.docx

Observe que se controla la excepción en caso no existan datos: se coloca un mensaje en el contexto de JSF para emplear luego el tag <h:messages /> en la página de login. 4.3. EMPLEANDO OTRAS IMPLEMENTACIONES DE JSF Como se había mencionado, JSF es una especificación, la cual está soportada por diversas implementaciones. Cada implementación proporciona un conjunto de tags que presentan determinada funcionalidad, la cual debe ser evaluada según las necesidades del proyecto. Lo bueno de trabajar con las implementaciones es que en la mayoría de casos, todas pueden coexistir dentro de una página. Una implementación ligera que contiene un único archivo .jar, no requiere configuración y no tiene dependencias ( a diferencia de Apache MyFaces) es PrimeFaces ( http://www.primefaces.org ). PrimeFaces proporciona un conjunto de componentes muy interesantes con un gran diseño y funcionalidad a la vez que le otorga un tratamiento especial al tema de Ajax como veremos en el siguiente ejemplo. Descargar la librería ( para JSF 2 ) desde el URL de Primefaces ( http://www.primefaces.org/downloads.html ) y configurar el Build Path del proyecto.

Page 141: 0.1 JPA.docx

No olvidar de configurar también el CLASSPATH del servidor. Si el servidor es Tomcat, debe quedar así:

Page 142: 0.1 JPA.docx

A continuación se muestra el encabezado de la página XHTM. Note que la librería de PrimeFaces está identificada como “p”:

Y el fragmento de código que emplea Tags de PrimeFaces:

Page 143: 0.1 JPA.docx

El proceso es bastante sencillo: se debe ingresar un ID que será verificado cuando el usuario presione el enlace de verificación. Este ID será validado disparando la acción denominada “nickAction” del Managed Bean utilizando AJAX. El tag p:ajaxStatus controlará el procesamiento de la petición AJAX y mostrará u ocultará la figura “ajax-loading.gif” El código del ManagedBean:

Page 144: 0.1 JPA.docx

Y Lo que se debe visualizar en el navegador. Observe el diseño más elaborado.

Page 145: 0.1 JPA.docx

JAVA SERVER FACES ( JSF ) LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, el alumno, construye una aplicación web de n-capas utilizando el modelo MVC y toda la funcionalidad provista por el framework JSF (Java Server Faces) a nivel de vista-controlador y por JPA (Java Persistence API) a nivel de modelo y la despliega dentro de un servidor de Aplicaciones Java EE compatible.

TEMARIO Tema 5: Tópicos avanzados de JSF II 5.1. Tablas JSF : Facets, dataTable y panelGrid. 5.2. Mantenimiento de Tablas ACTIVIDADES PROPUESTAS Los alumnos desarrollan aplicaciones web con JSF aprovechando las caracteristicas aprendidas sobre el Framework y generando pantallas que manejen datos en formato de tablas.

TEMA 5: TÓPICOS AVANZADOS DE JSF II 5.1 TABLAS EN JSF: Tag <f:facet /> Este tag establece que el componente anidado tiene una relación especial con el componente padre. Un “facet” representa una sección identificada con un nombre (el único atributo que tiene es “name”) dentro de un componente UI que actúa como contenedor. Normalmente se puede observar su utilización con componentes UI complejos ( como PanelGrid o DataTable ). Por ejemplo, los títulos que forman el encabezado de una tabla, en estricto, no forman parte de la relación con el componente padre, por tanto son candidatos a ser definidos como “facets”. Durante el “rendering” del componente padre, todos los tags “facet” son mostrados también. Ejemplo:

Esto mostrará algo similar a esto ( asumiendo que el valor de “beanLogin.clave” es “TEST1”

Tag <h:column />

Page 146: 0.1 JPA.docx

Este tag sirve como un “hijo” inmediato del tag <h:dataTable>. Sirve para la definición de columnas y puede ser equipado con “facets” llamados “header” y “footer” para crear encabezados y pies en las tablas.

Los atributos que soporta son:

Tag <h:dataTable /> Este tag permite solucionar aquella situación en la cual el controlador genera una lista de datos de tamaño variable y el desarrollador se enfrenta al problema de generar la página de salida sin tener la obligación de usar scripting o hacer iteraciones. Este tag genera una tabla HTML a partir de una colección de objetos, donde los componentes anidados ( tag <f:column> ) son responsables de mostrar las columnas de la tabla. Las columnas pueden contener cualquier tipo de componente. El cuerpo de la tabla se muestra dentro del tag HTML <tbody>. Los datos se muestran en celdas y las filas se van agregando a medida que se completa la cantidad de columnas definidas. Los eventos que soporta el componente son: onclick, ondblclick, onkeydown, onkeypress, onkeyup, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup. Los atributos de formato/agrupamiento son:

Page 147: 0.1 JPA.docx
Page 148: 0.1 JPA.docx

Los atributos “core” que soporta son:

Los atributos de estilo:

La sintaxis básica es:

Page 149: 0.1 JPA.docx

Donde el tipo de dato de “value” puede ser: Array, List, ResultSet, Result (JSTL), DataModel (JSF). Ejemplo 1:

Asumiendo que el Managed Bean denominado “company1” tienen un atributo “programmers” que devuelve un arreglo de Programadores. Se puede obtener la siguiente pantalla:

Ejemplo 2: Ahora usando encabezados y definiendo “facets” ( tag <f:facet> )

Page 150: 0.1 JPA.docx

Genera la siguiente pantalla:

Ejemplo 3: Usando estilos Note que el encabezado de la tabla tiene un estilo. Asi también, las filas pares e impares se manejan con estilos diferentes (obviamente la Hoja de estilos dee estar definida como recurso en la aplicación ).

Page 151: 0.1 JPA.docx

Se mostrará una pantalla similar a la siguiente:

Tag <h:panelGrid /> Este tag genera una tbla HTML que sirve como contenedor para otros componentes. Los componentes hijos son visualizados como celdas. Los eventos que soporta: onclick, ondblclick, onkeydown, onkeypress, onkeyup, Onmousedown, onmousemove, onmouseout, onmouseover y onmouseup. Algunos de los atributos:

Page 152: 0.1 JPA.docx

Los atributos “core” que soporta son:

Page 153: 0.1 JPA.docx

DATAMODEL Un DataModel es una abstracción arbitraria alrededor de alguna tecnología que puede ser usada para adaptar una variedad de fuentes de datos para ser empleados por componentes JSF de tal forma que soporten el procesamiento fila por fila por parte de los componentes hijos. La colección de datos se modelo como una colección de filas de objetos, las cuales pueden ser accedidas por un cursor ( que inicia en cero ) conocido como “row index”. La API propociona una serie de mecanismoa para posicionar el cursos y recuperar los objetos. 5.2 MANTENIMIENTO DE TABLAS: Se presenta un ejemplo sencillo de mantenimiento usando tablas. Crear una clase “Item.java” que tenga la siguiente estructura (no olvidar los getter/setter )

Page 154: 0.1 JPA.docx

Crear una clase “Bean.java” ( que es el managed bean de la aplicación ) que tenga la siguiente estructura. Observe que se utiliza la clase DataModel:

Page 155: 0.1 JPA.docx

Ahora codificar los métodos:

Page 156: 0.1 JPA.docx

Y el método que controla la edición:

No olvidar los getter/Setter de “ítem”, “model” y “list”. Ahora codificar el FaceLet. La primera parte de la página es:

Hasta aquí se debe mostrar los datos y los botones de edición y borrado. Ahora codificar la parte de edición:

Page 157: 0.1 JPA.docx

El resultado final es una pantalla similar a la siguiente, que permite la edición, eliminación y adición de elementos en una tabla.

Page 158: 0.1 JPA.docx

BIBLIOGRAFÍA Libros: Struts 2 in Action Donald Brown, Chad Micheal Davis, Scott Stanlick Ed. Manning Press Starting Struts 2 Ian Roughley Info Q Enterprise Software Development Series. Pro JPA 2 : Mastering the Java API Persistence Mike Keith , Merrick Schincariol Ed. Apress The Complete Reference : Java Server Faces 2.0 Chris Schalk , Ed Burns, James Holmes Ed. Mc Graw Hill Beginning JSF™ 2 APIs and JBoss® Seam Kent Ka Iok Tong Ed. Apress Páginas Web: JSF: http://java.sun.com/javaee/javaserverfaces/reference/docs/index.html Documentación de la implementación JSF Mojarra: http://javaserverfaces.java.net/users.html

Page 159: 0.1 JPA.docx

JPA:http://www.oracle.com/technetwork/articles/javaee/jpa-137156.html http://schuchert.wikispaces.com/JPA+Tutorial+1+-+Getting+Started Struts 2 http://struts.apache.org/2.2.1/index.html

Este curso requiere las siguientes herramientas de software : Java JDK Entorno integrado de desarrollo o IDE Servidor de Aplicaciones Base de datos Framework Struts 2 Framework JPA Framework JSF

Rational Application Developer IDE : Descargar el software “IBM Rational Application Developer for WebSphere Software” desde la página web de IBM: http://www.ibm.com/developerworks/downloads/r/rad/?S_CMP=TRIALS

Page 160: 0.1 JPA.docx

HERRAMIENTA #5: Librerías de Struts 2 Del sitio web de la Fundación Apache, obtenemos las librerías del framework Struts 2 La última versión liberada es la 2.2.1

Escoger una de las opciones de los archivos .ZIP. Con la opción de “Full Distribution” está más que suficiente:

Page 161: 0.1 JPA.docx

ANEXO 2: CONFIGURAR TOMCAT CON JSF Si se emplea JSF 2 con Apache Tomcat debe realizarse la siguiente configuración en el servidor: PASO 1: Descargar las siguientes librerias de la página web del proyecto JSF Mojarra. jstl-api-1.2.jar jstl-impl-1.2.jar el-impl-1.1.jar el-api-1.1.jar jsf-api.jar jsf-impl.jar

Page 162: 0.1 JPA.docx

PASO 5: En el tab “Classpath” seleccionar “User-Entries” y agregar la librerías descargadas.

Page 163: 0.1 JPA.docx

PASO 6: Adicionalmente agregar las librerías de servlet-api.jar y jsp-api.jar que están en la carpeta “lib” del servidor Tomcat.

Page 164: 0.1 JPA.docx

Java & Struts2 & Spring & Hibernate & Eclipse Tutorial

Introducción

Apache StrutsStruts es una herramienta de soporte para el desarrollo de aplicaciones Web bajo el patrón MVC bajo la plataforma Java EE (Java Enterprise Edition). Struts permite reducir el tiempo de desarrollo. Su carácter de "software libre" y su compatibilidad con todas las plataformas en las que Java Entreprise esté disponible lo convierten en una herramienta altamente disponible.

El 5 de marzo de 2013, Struts 1 llegó al final de su vida y dejó de estar oficialmente soportado.1

Struts 2 es un nuevo framework (anteriormente conocido como WebWork 2) que introdujo algunas mejoras sobre Struts 1, de cara a simplificar las tareas más comunes en el desarrollo de aplicaciones web, así como mejorar su integración con AJAX, etc.

Struts se basa en el patrón de arquitectura de software Modelo-Vista-Controlador (MVC) el cual se utiliza ampliamente y es considerado de gran solidez. De acuerdo con este Framework, el procesamiento se separa en tres secciones diferenciadas llamadas el modelo, las vistas y el controlador.

Spring Framework

Page 165: 0.1 JPA.docx

Spring es un framework para el desarrollo de aplicaciones y contenedor de inversión de control, de código abierto para la plataforma Java.2

Si bien las características fundamentales de Spring Framework pueden ser usadas en cualquier aplicación desarrollada en Java, existen variadas extensiones para la construcción de aplicaciones web sobre la plataforma Java EE. A pesar de que no impone ningún modelo de programación en particular, este framework se ha vuelto popular en la comunidad al ser considerado una alternativa, sustituto, e incluso un complemento al modelo EJB (Enterprise JavaBean).

Hibernate es una herramienta de Mapeo objeto-relacional (ORM) para la plataforma Java (y disponible también para .Net con el nombre de NHibernate) que facilita el mapeo de atributos entre una base de datos relacional tradicional y el modelo de objetos de una aplicación, mediante archivos declarativos (XML) o anotaciones en los beans de las entidades que permiten establecer estas relaciones.

Hibernate es software libre, distribuido bajo los términos de la licencia GNU LGPL.

Ejercicio…Crear nuevo proyecto

File>New>Dynamic Web Projecto Project name: Eventso Target runtime: <none>o Dinamic Web module version: 2.4o Configuration: Default

Finish

Nos creara nuestro proyecto similar a este…

Page 166: 0.1 JPA.docx

Vamos a empezar por la simple creación de una página de índice estático. En la ventana Explorador de proyectos, haga clic derecho en WebContent> New> Html página. Para el nombre de archivo, simplemente escriba "índex" y haga clic en Finalizar.

o Tenga en cuenta que el archivo de nombre de capitalización asuntos del mundo de Java, así que tenga cuidado con este tutorial.

Un contenedor de servlets (o simplemente "servidor") es un servidor java como Tomcat que se ejecuta la aplicación para usted (análogo a IIS en el Mundo .Net). Para fines de desarrollo, necesitamos una de éstas creado en Eclipse para que podamos ver nuestra aplicación, ya que toma forma. Se le pedirá los datos para crear un contenedor de servlets.

o Elija Básico> J2EE Vista previa, así como "Utilizar siempre este servidor, a continuación, haga clic en Finalizar. Más adelante en este documento que nos conectaremos con Tomcat, pero esto va a hacer por ahora.

o O puede escoger uno de su preferencia, si ya conoce de servidores y como configurarlos.

Dependiendo de la configuración de Java de su sistema, es posible que vea algunos ajustes para 'entorno de ejecución de servidor, puede dejar estos valores como los valores por defecto.Eclipse debería mostrar ahora el servidor como se inició en la ficha servidores en la parte inferior de la pantalla:

Cuando se hace eso, usted puede iniciar su navegador y vaya a http://localhost:8080/Events. Usted debe ver una página en blanco con 'Insert title here' como título:

Si has llegado hasta aquí, muy bien, el entorno de desarrollo está todo listo y que está funcionando.

Ahora vamos a ir de nuevo en Eclipse y lo puso en el tradicional 'hola mundo' (o lo que te apetezca). En eclipse, editar los eventos \ WebContent archivo \ index.html así:

Page 167: 0.1 JPA.docx

Después de editar y guardar el archivo, se dará cuenta a la vista de los "servidores" que va a decir 'a publicar' por un tiempo:

Esto es porque cuando usted hace cambios a su aplicación, es necesario publicar esas ediciones en el contenedor de servlets antes de poder verlos en su navegador. Después de un tiempo que debe asentarse de nuevo a 'empezar, sincronizada' de nuevo.

Una vez que se ha publicado y se sincroniza de nuevo, volver a entrar en tu navegador y pulse actualización:

Usando SiteMesh para una página maestra

Page 168: 0.1 JPA.docx

La mayoría de las aplicaciones tendrán algo de HTML común que desea compartir entre todas sus páginas. Esto por lo general consistirá en la barra de menú, css, logos, etc SiteMesh es una buena manera de lograr esto, como Struts no tiene una construida en forma de hacer esto. Este código HTML común se conoce como una página principal en Asp.net, o una plantilla en otra parte.

Ir a http://www.opensymphony.com/sitemesh/download.action y descargar la última JAR versión:

A continuación, arrastre y suelte el archivo '. SiteMesh-* jar' archivo descargado desde el explorador en su ventana de eclipse, dejándolo caer sobre los eventos \ WebContent \ WEB-INF carpeta \ lib en el explorador de proyectos.

Si alguna vez tiene problemas que arrastran los archivos en la carpeta lib en Eclipse, usted puede tener que descomprimirlos primero (he tenido problemas de arrastrar y soltar desde el interior de un archivo zip directamente en Eclipse).

Como alternativa, puede copiarlo en su 'C: \ \ eclipse_workspace Eventos \ WebContent \ WEB INF \ lib de la carpeta y, a continuación, haga clic derecho -> Actualizar en la carpeta lib en el explorador de proyectos:

Por favor, recuerde estos pasos para incluir archivos Jar en su aplicación, ya que va a ser algo que vamos a hacer con bastante frecuencia. Si, más adelante, alguna vez ves un error en la consola como una "clase no encontrada excepción", en primer lugar comprueba que has puesto todos los tarros de la carpeta lib y que ha refrescado en el explorador de proyectos Eclipse

Lo siguiente que necesitamos para incluir JSTL en el proyecto, ya que será utilizada por nuestra plantilla maestra SiteMesh. JSTL proporciona archivos JSP habilidades extra que utilizaremos más adelante para que la plantilla va a seleccionar la pestaña de menú correcto y mostrar el submenú correcta. Descarga jstl-1.2.jar desde aquí:

http://download.java.net/maven/1/jstl/jars/jstl-1.2.jar

Page 169: 0.1 JPA.docx

Y los agregamos a nuestro proyecto

Una vez que haya descargado el JAR, copiarlo en WEB-INF carpeta lib de su proyecto WebContent \ \ como lo hizo para el Jar SiteMesh.

Ahora tenemos que copiar en assets que son utilizados por la plantilla para este sitio. Crear una carpeta de 'activos' bajo WebContent y copiar en todos los archivos del archivo zip que viene con este tutorial (en el enlace para obtener el archivo zip se encuentra en mi blog, para la dirección de ver la primera página de este documento). Una manera fácil de hacer esto es arrastrar la carpeta de 'activos' desde el Explorador de Windows y colóquelo en 'WebContent' en Eclipse. A continuación, actualice la carpeta en el explorador de proyectos:

En caso de no encontrar estas imágenes colocar, las que gusten.

Page 170: 0.1 JPA.docx

El siguiente paso, es necesario crear la carpeta SiteMesh \ WebContent donde la plantilla main.jsp irá.

Si abre el archivo main.jsp y echar un vistazo, es básicamente un archivo HTML con un par de etiquetas especiales JSP. El único importante es la línea <decorator:body />. Se trata de un marcador de posición que se reemplaza con el contenido de la <body> ... </ body> de sus páginas.

Además, hay el <c: if ... y otros fragmentos de código JSTL esparcidos a través de ella para destacar y mostrar las partes apropiadas del menú, dependiendo de la página que el usuario se encuentra en.

Page 171: 0.1 JPA.docx
Page 172: 0.1 JPA.docx
Page 173: 0.1 JPA.docx

Apuntes

Ejemplo 1Tabla: PersonaColumnas: id_persona (Integer), nombre(varchar), apellidop(varchar),apellidom(varchar), fecha_nac(DATETIME)

Se crea una clase Persona Se declaran las variables private

Int idPersona;String nombre;String apellidoPaterno;String apellidoMaterno;Date fechaNacimiento;

Creamos los métodos, propiedades setters getters, utilizando las anotaciones o @Entity @Table @Id @Column @Temporal

Page 174: 0.1 JPA.docx

Cuando el nombre de la propiedad coincide con el nombre de la columna es posible omitir el parámetro name de Column, para este ejemplo el único campo que coincide es “nombre”, lo mismo pasa con el @Table, si el nombre de la clase coincide con el nombre de la tabla se puede omitir Es posible colocar las anotaciones en los métodos en lugar de propiedades, quedando

Page 175: 0.1 JPA.docx

persistence.xmlRecuerda que en JDBC e Ibatis las sentencias DML (Data Manipulation Language) trabajan sobre "Tablas" y son:

SELECT INSERT DELETE UPDATE

Mientras que en JPA, las sentencias DML trabajan sobre "Entidades" y deben aplicarse mediante el EntityManager. Estas sentencias son métodos del EntityManager que se aplican sobre la entidad y son:

select : equivale al select de SQL pero se aplica sobre "entidades" find : equivale a la busqueda de una entidad basado en su PK persist : equivale a un insert. merge: equivale a un update. remove: equivale a un delete. refresh: equivale a una re-lectura de la entidad (refresco desde la base de datos).

No te confundas: 

en JDBC e IBatis se usan TABLAS relacionales. en JPA se usan "Entidades" que previamente han sido definidas dentro del archivo

persistence.xml.

orm.xmlSin embargo, la otra opción es usar el archivo de "mapeo" llamado orm.xml que se ubica en el mismo directorio que el anterior, es decir, en META-INF.

Cuál es la diferencia entre orm.xml y persistence.xml? que si no tenemos un wizard que haga las cosas ... tendremos que escribir el contenido del archivo a

mano. que quitamos todas las anotaciones de la clase Java y ahora las registramos como "tags" XML dentro del

orm.xml

Page 176: 0.1 JPA.docx

EntidadFinalmente, hablaremos del ciclo de vida de una entidad como se aprecia en el gráfico siguiente:

Page 177: 0.1 JPA.docx

Lo más saltante es que no podemos efectuar operaciones con la entidad si es que primero no la colocamos en estado "managed", es decir, si primero el Entity Manager no la tiene reconocida (o cargada).

Por otro lado, cada evento que sucede en el Entity Manager (las operaciones básicas sobre la entidad) generan o disparan una serie de acciones que se conocen como los "Callbacks" o Listeners.

Las anotaciones que proporciona JPA para manejar los “Callbacks” son:

@PostLoad : Se ejecuta luego de un “refresh” a la entidad. @PrePersist: Se ejecuta antes de insertar la entidad. @PostPersist: Se ejecuta después de haber insertado la entidad. @PreUpdate: Se ejecuta antes de un update a la entidad. @PostUpdate: Se ejecuta después de un update a la entidad. @PreRemove: Se ejecuta antes de eliminar la entidad en la base de datos. @PostRemove: Se ejecuta después de haber eliminado a la entidad.

Dichas anotaciones las podemos colocar dentro de métodos de la misma entidad, en cuyo caso el método no recibe como parámetro a la entidad en sí.O tambien, apuntar a otra clase que sea la que contenga a los métodos, en cuyo caso, los método reciben como parámetro a la entidad. Para ello hay que usar la anotación @EntityListener en la entidad para apuntar a la clase externa.

Page 178: 0.1 JPA.docx

Callbacks – JPA

Objetivo. Conocer el manejo de los eventos asociados al ciclo de vida de una entidad JPA

Page 179: 0.1 JPA.docx

JPA : Troubleshooting #1En este post hablaremos acerca de la configuración que debe tenerse en cuenta para que funcione una aplicación sin presentar un error del tipo siguiente:

Para ello, sabemos que en el archivo persistence.xml existe un tag llamado <persistence-unit> que tiene un atributo llamado "name". Dicho nombre debe coincidir exactamente con el que utilizamos en el programa Java para crear la factoría y después el EntityManager Sea en Java SE o en Java EE (es lo mismo).

Presten atención a la figura para mayor claridad :

Page 180: 0.1 JPA.docx

Si no coinciden los nombres, aparecerá el error.

JPA: Relaciones One To One

En este post comentaremos el tipo de relación de uno-a-uno que se aprendió durante los cursos de Anáisis y Diseño con UML.

Básicamente implica que una entidad está relacionada con otra, pero tiene sus bemoles: 

Existe la relación nomal (analiza este ejemplo ). Pero también existe la relación inversa (analiza este ejemplo ).

De esta forma, es posible consultar las entidades por los dos lados de la relación.

Este tipo de relación requiere de dos anotaciones:

@OneToOne : para especificar las características lógicas de la relación

Page 181: 0.1 JPA.docx

@JoinColumn: para especificar las características físicas de la relación. Es decir, cuales son las columnas de JOIN de las tablas.

Descarga e importa esta base de datos MySQL y lee el siguiente PDF de la clase.

JPA : Generación de Llave Primaria

En este post comentaremos acerca de las modalidades para la generación de un PK simple ( ojo que también hay PK's compuestas ).

Además de la anotación @Id se emplea la anotación @GeneratedValued con el atributo "strategy". Básicamente hay cuatro valores para el atributo:

strategy=GenerationType.AUTO strategy=GenerationType.TABLE strategy=GenerationType.SEQUENCE strategy=GenerationType.IDENTITY

El AUTO le dice a JPA que busque la mejor forma de generación de secuencias. Dependiendo de la base de datos a usar se puede manejar "secuencias" (oracle) o "autoincrementos" (MySQL). Para no complicarnos mucho, en este post sólo mencionaremos el uso de la opción TABLE, que es una buena alternativa cuando queremos controlar la generación de la secuencias en una tabla ( algo así como una tabla de correlativos ).

Forma de utilización #1:Si sólo se especifica la anotación sin indicar la tabla, JPA busca (o genera ) una tabla llamada "sequence". La tabla requiere de dos columnas: una conteniendo el identificador para generar la secuencia y la otra columna contiene el último valor generado. Cada fila de la tabla es un generador diferente para los ID’s.

Ejemplo:

Forma de utilización #2:

Page 182: 0.1 JPA.docx

¿ Qué sucede si deseamos indicar una tabla específica ?. Debemos agregar una anotación más: @TableGenerator Ahora debemos indicar algunas características de la tabla (que si bien sigue manteniendo la estructura mencionada en la forma de uso #1 ), requiere el "mapeo" de algunas cosas:

A diferencia de la estrategia IDENTITY, en ésta estrategia el valor de la PK ya está disponible desde el momento en que se hace el persist.

Page 183: 0.1 JPA.docx

Incluir librerías JAR a nuestro proyecto propiedades de nuestro proyecto Seleccionamos "Java Build Path", luego "Libraries" y le damos a "Add External JARs" …

Ejercicio JSFNuevo proyecto

Dinamic web ProjectSin servidorVersión 2.5

Opciones del proyectoProject faces

Opción JSFUsar la librería Apache MyFacesSi no se encuentra descargarla