Integración de JSF y JPA

RECU-0822 (Recurso Referencia)

Descripción

Al desarrollar una aplicación puede surgir la situación en la que no sea necesario emplear una capa de negocio entre la capa de presentación y la de persistencia, debido a la poca complejidad de la funcionalidad a desarrollar. En caso de que se desee integrar directamente JSF con JPA, será recomendable tomar como base los siguientes ejemplos:

Definición de la unidad de persistencia

Una unidad de persistencia requiere un DataSource configurado en el servidor de aplicaciones que normalmente es usado por el proveedor de persistencia para conectar con la base de datos. Normalmente el contenedor Java EE lo provee, pero si se usa JPA fuera del contenedor se debe facilitar la configuración JDBC como un fichero de propiedades específico del proveedor como, por ejemplo, un fichero persistence.xml:

<persistence
      xmlns = "http://java.sun.com/xml/ns/persistence" version = "1.0">
   <persistence-unit name = "actionBazaar">
     <provider>oracle.toplink.essentials.PersistenceProvider</provider>
     <class>actionbazaar.persistence.Bid</class>
     <class>actionbazaar.persistence.Item</class>
     <properties>
        <property name = "toplink.jdbc.driver"
           value = "oracle.jdbc.OracleDriver"/>
        <property name = "toplink.jdbc.url"
            value = "jdbc:oracle:thin:@//localhost:1521/ORCL"/>
        <property name = "toplink.jdbc.user" value = "scott"/>
        <property name = "toplink.jdbc.password" value = "tiger"/>
     </properties>
   </persistence-unit>
</persistence>

Creación de un EntityManager a través de EntityManagerFactory

Un EntityManager puede no estar accesible en un registro JNDI o accesible mediante inyección de dependencias cuando se usa JPA fuera de un contenedor Java EE. Por lo tanto, es necesario crear un EntityManager desde la factoría EntityManagerFactory que puede ser creada mediante la clase factoría javax.persistence.Persistence. Esto es típico en los casos que se utilizan JTA en entornos como Java SE o utilizando contenedores web como Tomcat (las transacciones JTA no están disponibles fuera de un contenedor Java EE). Se recomienda generar tantos EntityManager como sean necesarios.

public class DatabaseWrapper {

@PersistenceUnit
   private EntityManagerFactory factory;
   private EntityManager mgr;

   @PostConstruct
   public void createEntityManager()
   {
     mgr = factory.createEntityManager();
   }
   @PreDestroy
   public void closeEntityManager()
   {
     mgr.close();
   }
}

Uso de anotaciones @PostConstruct y @PreDestroy para asegurar el contexto de persistencia

Se controla la creación y cierre de la EntityManager en su métodos de ciclo de vida, así que sabemos que el contexto de persistencia está en vigor durante la sesión de usuario. Para ello es necesario crear y cerrar el EntityManager con las anotaciones.

@PostConstruct
   public void createEntityManager()
   {
     mgr = factory.createEntityManager();
   }
   @PreDestroy
   public void closeEntityManager()
   {
     mgr.close();
   }

Control de los límites de la transacción mediante el uso de la interfaz EntityTransaction y una instancia manejada por el EntityManager

Mediante el uso de la EntityTransaction definimos:

  • El inicio de la transacción mediante el método begin().
  • El acierto mediante el método commit().
  • El manejo de la excepción.
  • La vuelta atrás en la transacción con el método rollback().
public void create(Manufacturer manufacturer) throws PreexistingEntityException, Exception {

EntityManager em = null;
       
try {

            em = getEntityManager();
            em.getTransaction().begin();
            em.persist(manufacturer);
            em.getTransaction().commit();

        } catch (Exception ex) {
            if (findManufacturer(manufacturer.getManufacturerId()) != null) {
                throw new PreexistingEntityException("Manufacturer " + manufacturer +
" already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

Cuando se utiliza JPA fuera del contenedor, tiene que asegurarse que se han incluido todos los archivos requeridos dentro del CLASSPATH.

Contenidos relacionados

Pautas
Área: Desarrollo » Construcción de Aplicaciones por Capas » Java
Código Título Tipo Carácter
LIBP-0049 Integración JSF - JPA Libro de pautas Directriz Recomendada