miércoles, 29 de diciembre de 2010

Seam: Error en org.jboss.seam.framework.Query.getCountEjbql()

Este método que genera la consulta para obtener el número de resultados posee varios errores/limitaciones a tener en cuenta.
1) Produce un error si la consulta contiene group by con más de un campo:
Este error se corrige modificando el código para que use count(*) en lugar de count(distinct + getGroupBy).
2) Aún corrigiendo lo anterior falla si la consulta posee más de un group by, ejemplo:
select e ..... where e.propiedad in (select o .... group by o.propiedad) group by e.propiedad.
La consulta anterior se podría resolver cambiando el group by de la subconsulta por distinct o.propiedad1,o.propiedad2 si sólo deseamos eliminar duplicados, pero en otro tipo de consultas que se necesite group by no sería posible.

viernes, 29 de octubre de 2010

Seam: Controlar conversaciones en la vista

Si queremos terminar una conversación mediante un enlace o botón hay que tener en cuenta lo siguiente:
- Si nuestra acción no produce una redirección a otra página no debemos usar ni <s:link> ni <s:button> ya que aunque indiquemos propagation="end", esto sólo introduce en la URL un parámetro que indica que se debe terminar la conversación y es en la navegación a la vista destino cuando se lee dicho parámetro y se termina la conversación. En su lugar usaremos <h:commandbutton>,<a4j:commandbutton>, <h:commandlink> o <a4j:commandlink> con la etiqueta <s:conversationpropagation type="end"> anidada.

lunes, 25 de octubre de 2010

JSF: Pasar acción como parámetro en panel modal

El escenario es el siguiente:
- Tengo un modal panel con un backbean/controlador de dicho moda panel
- Este modal panel se va a usar en distintas vistas
- Tiene una misma acción que en cada vista ejecuta un método distinto

Solución 1:
- Crear en el controlador un método para cada acción
- Enviar como parámetro o en cualquier propiedad del controlador la acción que se debe ejecutar
- En el modal panel deben existir un commandLink por cada acción y usar el parámetro anterior
para determinar cual renderizar

Solución 2(a probar):
- Pasar la acción como parámetro y usar la clase org.jboss.seam.core.Expressions para invocar el método.

lunes, 18 de octubre de 2010

JSF: Método para saber si una petición es postback

protected boolean isPostBack() {
FacesContext facesContext = FacesContext.getCurrentInstance();
return facesContext.getRenderKit().getResponseStateManager().isPostback(facesContext);
}

domingo, 5 de septiembre de 2010

JSF: Obtener ServletContext

Obtener el objeto ServletContext para obtener la ruta real de cualquier directorio de nuestra aplicación. Útil para guardar ficheros:

ExternalContext external = FacesContext.getCurrentInstance().getExternalContext();
ServletContext servletContext = (ServletContext) external.getContext();
String path = servletContext.getRealPath("/..");

viernes, 6 de agosto de 2010

Propagación del contexto de persistencia

La propagación de contexto de persistencia se produce sólo para los EntityManager gestionados por el contenedor. En un EntityManager gestionado por el contenedor en el contexto de una transacción (caso común en un entorno Java EE), la propagación de transacciones JTA es la misma que la del contexto de persistencia. En otras palabras, los EntityManagers gestionados con ámbito de transacción obtenidos dentro de una misma transacción JTA comparten el mismo contexto de persistencia. En términos de Hibernate, esto significa que todos los gestores comparten la misma sesión.

Importante: el contexto de persistencia nunca es compartido por diferentes transacciones JTA o entre EntityManagers que no vienen del mismo EntityManagerFactory. Hay algunas
excepciones dignas de mención para la propagación del contexto al utilizar contextos extendidos de persistencia:

• Si, un SLSB, MDB o SFSB con un contexto de persistencia en ámbito de transacción invoca un método de un SFSB con contexto de persistencia extendido en la misma transacción JTA, se lanza una IllegalStateException.

• Si un SFSB con un contexto de persistencia extendido invoca a un SLSB o SFSB con contexto de persistencia de ámbito de transacción dentro de la misma transacción JTA, el contexto persistencia se propaga.

• Si un SFSB con un contexto de persistencia extendido llama a un SFSB o SLSB dentro de un contexto distinto de transacción JTA, el contexto de persistencia no se propaga.

• Si un SFSB con un contexto de persistencia extendido instancia otro SFSB con un contexto de persistencia extendido, el contexto de persistencia extendido es heredado por el segundo SFSB. Si el segundo SFSB sesión se llama con un contexto de transacción diferente que el primero, un IllegalStateException es lanzada.

• Si un SSB con contexto de persistencia extendido llama a un SFSB con un contexto persistencia extendido diferente en la misma transacción, una IllegalStateException es lanzada.

viernes, 30 de julio de 2010

Seam: Eliminar el mensaje "Transaction Failed"

Si queremos eliminar el mensaje "Transaction Failed" que aparece cada vez que falla una transacción y que Seam automáticamente pone en el "FacesMessages" se puede hacer de dos formas:

1. Añadiendo al fichero seam.properties la siguiente línea:

org.jboss.seam.transaction.facesTransactionEvents.transactionFailedMessageEnabled=false

2. Añadiendo al fichero components.xml la siguiente configuración:

<component name="org.jboss.seam.transaction.facesTransactionEvents">
<property name="transactionFailedMessageEnabled">false</property>
</component&gt
;

sábado, 17 de julio de 2010

Contexto de persistencia extendido

Cuando inyectamos un contexto de persistencia extendido con @PersistenceContext(type = EXTENDED) en primera instancia estamos indicando que el ciclo de vida del contexto de persistencia y del EntityManager están ligados al ciclo de vida del bean en el que lo injectamos y no de la transacción activa en el momento de la llamada a un método de negocio. Esto afecta a las operaciones sobre entidades de la siguiente manera:

En un contexto de persistencia EXTENDIDA, todas las operaciones de sólo lectura del EntityManager pueden ejecutarse al margen de una transacción (find (), getReference (), refresh (), y consultas de lectura). Algunas operaciones de modificaciones pueden ejecutarse al margen de una transacción, pero se ponen en cola hasta que el contexto persistencia se une a una transacción: este es el caso de persist (), merge (), remove (). Algunas operaciones no pueden ser llamadas fuera de una transacción: flush (), lock (), y consultas de eliminación de tipo update/delete.

viernes, 11 de junio de 2010

Richfaces: sortBy y filterBy fallan con tooltips.

Si definimos los atributos filterBy y sortBy de una <rich:column> y dentro de la columna tenemos un componente <rich:tooltip>, al intentar ordenar o filtrar no se muestran los resultados.

jueves, 10 de junio de 2010

Seam: obtener vista actual

Mediante EL se puede obtener la vista actual con #{view.viewId} y #{facesContext.viewRoot.viewId}. En código se puede obtener con FacesContext.getCurrentInstance().getViewRoot().getViewId().

lunes, 7 de junio de 2010

Mensaje de error en <s:decorate>

Hay que tener cuidado con los ids al usar el tag <s:decorate>. Cuando creamos un proyecto con seam-gen basándonos en una BBDD existente, en los formularios de edición de las entidades nos crea un código como el siguiente:


<s:decorate id="txDescripcion" template="layout/edit.xhtml">
<ui:define name="label">Descripción</ui:define>
<h:inputTextarea id="txDescripcionField"
cols="80"
rows="5"
required="true"
value="#{amSelected.txDescripcion}"/>
</s:decorate>

Si cometemos el error de dar el mismo id al tag <s:decorate> y al input (del tipo que sea), cuando se produzca un error de validación mostrará el icono de error y cambiarán los estilos pero no el mensaje de error.

martes, 1 de junio de 2010

Jboss Seam: "propagation=none" en <s:link> o <s:button>

Si tenemos una conversación activa y pulsamos sobre un enlace que posea el atributo "propagation=none", esto provocará que se abandone (es equivalente a Conversation.instance().leave()) la conversación actual y aquellas anidadas que posea o la anidada en la que estemos y su padre. Si otra vez accedemos a la misma página, se creará una nueva conversación. Si en nuestra aplicación ejecutamos cualquier acción que termine una conversación y existen conversaciones abandonadas, éstas también serán destruidas.