Pautas integración Seam - JPA

LIBP-0052 (Libro de pautas)

JBoss Seam Fue originalmente diseñado para integrar todas las especificaciones salidas de Java EE5, y ser un puente perfecto para la integración de JSF y EJB3. Sin embargo, Seam es extremadamente flexible y puede permanecer sin EJB.En Seam cualquier POJO anotado con @Name puede convertirse en un componente manejado. Se pueden construir aplicaciones Seam solamente basadas en POJO's. Vamos a ofrecer una serie de recomendación para hacer una buen a integración de Seam con JPA sin la utilización de EJB3.

Pautas

TítuloCarácter
Configuración necesaria para suplir a EJB3Obligatoria
Usar POJOs en lugar de beans de EJB3Obligatoria
Evitar usar algunas características de EJB3 no soportadas fuera de su contenedorRecomendada

Configuración necesaria para suplir a EJB3

Para desarrollar aplicaciones fuera del contenedor de EJB3 es necesario configurar Seam para que desarrolle los servicios esenciales delegados en el contenedor de EJB3. Puedes cambiar cualquier aplicación Seam para que convierta de los beans de sesión al uso de POJOs.

En primer lugar es necesario dar de alta el contexto de persistencia y el EntityManager para usarlos en un entorno no EJB3. Se debe de especificar dentro del fichero persistence.xml, el proveedor de cache y el mecanismo para manejar las transacciones que realiza el contenedor EJB3 de forma automática para los beans de sesión pero que tenemos que realizar para los POJOs. Un ejemplo de fichero de configuración sería el siguiente, definiendo al proveedor como Hibernate y el manejo de transacciones mediante JTA

<persistence>
   <persistence-unit name="helloworld" transaction-type="JTA">

       <provider>
           org.hibernate.ejb.HibernatePersistence
       </provider>

       <jta-data-source>
           java:/DefaultDS
       </jta-data-source>

       <properties>
          <property name="hibernate.dialect"
             value="org.hibernate.dialect.HSQLDialect"/>
          <property name="hibernate.hbm2ddl.auto"
             value="create-drop"/>
          <property name="hibernate.show_sql"
             value="true"/>
          <property name="hibernate.cache.provider_class"
             value="org.hibernate.cache.HashtableCacheProvider"/>
          <property name="hibernate.transaction.manager_lookup_class"
             value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
          </properties>
   </persistence-unit>
</persistence>

Además para que Seam construya un EntityManager y lo inyecte en los POJO, debemos de indicarlo en el archivo components.xml. Debe de existir un componente <core:entity-manager-factory name="....."/> que construya el EntityManager desde el PersistenceUnit definido. Con ello aseguramos el correcto funcionamiento de la inyección. El ejemplo es el siguiente

<components ...>
   <core:init debug="true"/>
   <core:manager conversation-timeout="120000"/>
   <core:entity-manager-factory name="helloworld"/>
   <core:managed-persistence-context name="em" entity-manager-factory="#{helloworld}"/>
</components>

Usar POJOs en lugar de beans de EJB3

En Seam cualquier POJO anotado con @Name puede convertirse en un componente manejado. Por lo tanto lo único necesario a realizar es incluir la anotación previamente al componente. A continuación tenemos un ejemplo:

@Name("manager")
public class ManagerAction { 
   @In (create=true) 
   private EntityManager em;
   ... ...}

Evitar usar algunas características de EJB3 no soportadas fuera de su contenedor

Usar POJOs en lugar de beans de EJB3 tiene sus pros y sus contras. Los POJOs son un poco mas simples de programar porque no necesitan ni interfaces ni anotaciones específicas de EJB3. Sin embargo se pierden algunas características importantes que no pueden utilizarse sin el contenedor EJB3, algunas de los principales servicios que se pierden por el uso de POJOs son los siguientes

  • La inyección @PersistenceContext no funciona en POJOs. Hay que inicializar el EntityManager en el fichero de configuración de Seam e inyectarlo en el POJO mediante la anotación @In
  • Los Seam POJOs no puede ser componentes message-driven.
  • No soporta las anotaciones @Asynchronous
  • No no pueden ser componentes @Webservice
  • No existen niveles del contexto de persistencia. Todos los contextos de persistencia son "extended"
  • No soporta el manejo de la seguridad que ofrece el contenedor
  • No hay soporte para manejo de la transacción por métodos declarativos. Seam puede configurarse para marcar una transacción de base de datos cuando se recibe la solicitud Web hasta que la página de respuesta se representa.