2011-05-06 18 views
5

Estoy usando la combinación Spring/Hibernate para mi proyecto, con operaciones CRUD estándar.Validar la existencia del objeto antes de eliminarlo o actualizarlo en Spring/Hibernate

Me pregunto, ¿es razonable validar la existencia del objeto antes de su eliminación o actualización? Si es así, ¿dónde está el lugar más apropiado para hacer, service o dao layer?

EDIT:
Lo sentimos, no hice el punto al principio cuando hice esta pregunta. El único motivo para verificar la existencia es lanzar una excepción amistosa al cliente de servicio (no DAO específico).

El problema es que tengo que hacer 'comprobación de existencia porque mi método de servicio a continuación es transaccional, y además de eso, estoy usando clases de ayuda HibernateTemplate y DaoSupport para la manipulación de sesiones en objetos DAO.

Según lo mencionado, la excepción Hibernate (en caso de eliminar una instancia no existente por ejemplo) se lanza en tiempo de compromiso, que está fuera de mi alcance, porque (supongo) la confirmación se ejecuta por PlatformTransactionManager en el objeto proxy, y No tengo la oportunidad de manejar esa excepción en mi método de servicio y volver a lanzar una excepción amistosa al cliente.

Pero incluso si sigo mi estrategia para comprobar la existencia antes de la eliminación, lo malo es que tengo problemas con NonUniqueObjectException en el caso de que instancia existen, porque volver a conectar (en tiempo de borrado) instancia ya cargado (en lectura tiempo de comprobación de existencia debida).

Por ejemplo:

//Existence checking in this example is not so important 
public void delete(Employee emp){ 
    Employee tempEmp=employeeDao.read(emp.getId()); 
    if(tempEmp==null) 
     throw new SomeAppSpecificException(); 
} 
//Existence checking in this example is maybe 'more logical'  
public void save(Assignment a){ 
    Task t=taskDao.read(a.getTask().getId()); 
    if(t==null) 
     throw new FriendlyForeignKeyConstraintException(); 
    Employee e=employeeDao.read(a.getEmployee().getId()); 
    if(e==null) 
     throw new EmployeeNotFoundExc(); 
    //...some more integrity checking and similar... 
    assignmentDao.save(a); 
} 

El punto es que sólo quiero tirar excepción agradable con el mensaje apropiado en el caso de las situaciones mencionadas (violaciónes de integridad y similares).

Respuesta

3

En términos de Hibernate, las operaciones de actualización y eliminación (y los métodos correspondientes en Session) se refieren a entidades persistentes. Su existencia es, por lo tanto, implícita y verificar nuevamente en su código es algo inútil - Hibernate lo hará por sí mismo y lanzará una excepción si ese no es el caso. Luego puede atrapar y manejar (o volver a lanzar) esa excepción.

En una nota lateral (basada en su código de muestra), no es necesario leer explícitamente la instancia que va a eliminar. Session proporciona el método load() que devolverá la instancia de proxy adecuada para pasar al método delete() sin llegar a la base de datos. Asume que la instancia asociada con PK dado existe y fallará (lanzará una excepción) más adelante si ese no es el caso.

Editar (basado en la clarificación pregunta):

Cuando dice que quiere lanzar una excepción "amigable" con el cliente, las definiciones de "amistosa" y "cliente" se vuelven importantes. En la mayoría de los escenarios de la vida real, su transacción abarcaría más que un simple método atómico "guardar()" o "eliminar()" en uno de sus servicios.

Si el cliente es local y no necesita transacciones separadas dentro de una interacción de cliente único (escenario típico - aplicación web ejecutándose en la misma VM con capa de servicio), generalmente es una buena idea iniciar/confirmar transacción allí (ver Open Session In View, por ejemplo). A continuación, puede capturar y manejar adecuadamente (incluidas las de envolver/volver a tirar, si es necesario) excepciones durante la confirmación.Otros escenarios son más complicados, pero en última instancia, la excepción se propagará a su cliente de "nivel superior"; es solo que desenvolverlo puede resultar complicado si necesita presentar la causa "raíz" al cliente de una manera "amistosa".

La conclusión, sin embargo, es que depende de usted. Si prefiere fallar rápidamente con su propia excepción (a expensas de escribir un código repetitivo), no hay nada realmente malo en eso.

+1

Nuevamente, gracias por la (s) respuesta (s) y paciencia con principiantes como yo. Tengo lo que sugieres, pero creo que mi enfoque del problema es un poco ingenuo. Solo quiero arrojar alguna excepción amistosa en una situación específica. Cambié mi pregunta porque al principio no describí el contexto en el que surgió mi pregunta. – slomir

+0

@slomir - De nada; ver mi actualización – ChssPly76

+1

Parece que acaba de golpear el punto de mi lucha. Ya leí acerca de la sesión abierta en el enfoque de Vista debido a mi problema de inicialización lenta en mi aplicación Flex/Spring/Hibernate. Para la comunicación, estoy usando el protocolo de comunicación remota AMF con la integración BlazeDS que además complica mi situación para la implementación de OSiV. Como parece (debido a que mi fecha límite está próxima), probablemente relajaré las validaciones de existencia y similares, y trataré de minimizar las consecuencias del antipatrón de sesión por operación. – slomir

Cuestiones relacionadas