Resource Local es un tipo de transaccionalidad que soporta JPA que delegar la responsabilidad de las transacciones al programador, de esta manera, el programador será el único responsable de abrir y cerrar las conexiones, realizar los Rollback y cerrar las conexiones no utilizadas.
En la sección pasada de este tutorial dimos una breve Introducción a Java Transaction API (JTA), otra forma de administrar las transacciones de forma automática por medio del Application Server. Resource Local es utilizado casi por completo en aplicaciones de escritorio o aplicaciones Core que corren de forma standalone y que por lo tanto no corren sobre toda la infraestructura que provee un Application Server forma. Las aplicaciones que decidan utilizar este tipo de transacciones deberá indicarlo al momento de crear el Persistence Unit del archivo persistence.xml:
<persistence-unit name=”JPA_PU” transaction-type=”RESOURCE_LOCAL”>
Otra de las cuestiones importantes a remarcar es que la inyección de dependencias (CDI) no estará disponible en ambientes Java SE, por lo que estaremos obligados a crear manualmente el EntityManager a través de EntityManagerFactory, para esto podemos crearlo de la siguiente manera:
EntityManagerFactory factory = Persistence.createEntityManagerFactory(“JPA_PU”);
EntityManager manager = factory.createEntityManager();
Lo primero que se debe de crear es el EntityManagerFactory, el cual se crea a partir de la clase Persistence y se le envía como parámetro el nombre del PersistenceUnit. Seguido, es creado el EntityManager a partir del EntityManagerFactory.
Trabajar con Transacciones Resource Local
Para trabajar con Resource Local es necesario familiarizarnos con la clase EntityTransaction:
package javax.persistence; public interface EntityTransaction { public void begin(); public void commit(); public void rollback(); public void setRollbackOnly(); public boolean getRollbackOnly(); public boolean isActive(); }
Mediante esta clase es posible controlar las transacciones de JPA, es obtenida a través del EntityManager con el método getTransaction. Esta clase una serie de métodos que nos permitirán controlar las transacciones. Los métodos son los siguientes:
- Begin: Se utiliza para iniciar una nueva transacción. Lanza una IllegalStateException cuando la transacción ya está activa.
- Commit: Realiza commit a la transacción activa. Lanza IllegalStateException cuando la transacción no está activa o RollbackException cuando se genera un error al realizar el commit
- Rollback: Realiza un Rollback de la transacción y echa atrás todos los cambios realizados durante la transacción. Lanza IllegalStateException cuando la transacción no está activa o PersistenceException ante cualquier posible error inesperado.
- setRollbackOnly: Marca la transacción para que se realice un Rollback después de terminar la ejecución (Se aconseja usar solo en EJB).
- GetRollbackOnly: Indica si la transacción ha sido marcada para hacer Rollback
- isActive: Retorna true si existe una transacción activa, false de lo contrario.
El siguiente ejemplo ilustra cómo es que suele utilizar la clase EntityTransaction:
public void saveEmployee(Employee emp){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("JPA_PU"); EntityManager manager = factory.createEntityManager(); try { manager.getTransaction().begin(); manager.persist(emp); manager.getTransaction().commit(); } catch (Exception e) { if(manager.getTransaction().isActive()){ manager.getTransaction().rollback(); } } }
Este es un simple método que guarda un nuevo empleado. Primero que nada, se crear el EntityManager como ya lo explicamos, luego en la línea 5 se abre una nueva transacción, para después realizar el guardado, en la línea 7 se realiza el commit. En caso de que algo salga mal, entonces el error cae en el Catch y se valida que exista una transacción activa (línea 9) para después proceder con el Rollbak (línea 10).
Como vemos, trabajar con Resource Local puede llegar a ser un poco más complicado, pero esa es la única alternativa si estamos trabajando con aplicaciones de Escritorio.