Estoy usando JPA con Hibernate como proveedor con transacciones manejadas por contenedor (JBoss AS 6.1.0.Final).Manejo de excepciones con JPA + Hibernate
Estoy tratando de implementar un manejo de excepciones muy detallado porque tengo una jerarquía de excepciones particular en mi aplicación para poder definir qué hacer en cada situación. Por lo tanto, he estado investigando durante horas y encuentro que la documentación es vaga y los ejemplos un poco crudos porque el manejo de excepciones siempre se omite "por el bien de la claridad" o es un simple bloque try-catch que maneja Exception e.
Por ejemplo, tome este código:
public void deleteCompany(ICompany company) throws MyException1, MyException2 {
if(entityManager != null){
if(company !=null) {
try {
ICompany companyReference= entityManager.getReference(Company.class, company.getId());
entityManager.remove(managedCompany);
entityManager.flush();
} catch(EntityNotFoundException companyDoesNotExist) {
//Wrap & Throw
}
} else {
throw new MyException1("An error occurred while attempting to save a null instance of a company");
}
} else {
throw new MyException2("The entity manager instance is null");
}
}
El bloque catch está en blanco porque ahí es donde estoy atascado ... no sé qué excepción debería tomar para alertar al sistema que el usuario estaba intentando eliminar un registro inexistente.
Mi pregunta concreta es: ¿Puedo detectar excepciones de Hibernate en ese bloque catch o tengo que atrapar las JPA? Encontré algunas fuentes que afirman que JPA envuelve las excepciones de los proveedores, pero eso me suena extraño. También descubrí que al llamar al método flush() es posible detectar las excepciones de manipulación y acceso a la base de datos, ya que el contenedor administra las transacciones y, por lo tanto, el compromiso entra en más pasos luego de invocar deleteCompany.
Gracias.
EDIT: Estoy arreglando las excepciones que capto con mis propias excepciones anotadas con @ApplicationException (rollback = true), para poder lanzarlas de nuevo y manejarlas más claramente.
EDIT 2: He actualizado mi código. La fusión antes de la eliminación persiste en la empresa si no está en la base de datos, lo que hace que la eliminación sea exitosa en todo momento. Ahora se lanzan las excepciones y estoy probando cómo se comporta en diferentes situaciones atrapando las excepciones de JPA como lo sugiere Perception.
EDIT 3: Ahora está funcionando! Resulta que el error estaba parcialmente en mi código debido a esa llamada de fusión. Obtener la referencia primero y luego intentar eliminarlo es el truco, de esa forma pude capturar una EntityNotFoundException, envolverla y lanzarla de nuevo.
Bonito consejo el que das aquí, no sabía que todos los temas eran excepciones de tiempo de ejecución, pero parece razonable pensar en las transacciones manejadas por contenedor y la reversión relacionada. Los atraparé y los envolveré en mis propias excepciones para arrojarlos de nuevo, pero también preservaré la excepción original. Solo una cosa ... ¿podré determinar la excepción en particular si capturo la PersistenceException? o es esta identificación un mal enfoque? – Gamb
Usted * puede * obtener la excepción del proveedor (se incluirá en la excepción de persistencia como 'causa '), pero no es una buena idea por varias razones. 1) No debe preocuparse por el proveedor, quiere poder cambiar de proveedor a voluntad sin cambiar su código. 2) Las implementaciones de los proveedores no siempre están bien documentadas, por lo que tratar de determinar el conjunto completo de excepciones puede ser un ejercicio inútil. – Perception
Ya veo. Perdón por molestar, pero aún no veo cómo voy a poder determinar si un objeto no se almacenó en la base de datos cuando invoco este método ... Encontré [este sitio] (http: //www.objectdb .com/api/java/jpa/exceptions) que se supone que enumera todas las excepciones JPA y la que parece ajustarse a mi dilema es javax.persistence.EntityNotFuundException, pero no aclara si será lanzado por un entityManager.remove() llame ... – Gamb