Curso:
1. Primeros pasos |
2. Modelo básico del dominio (1) |
3. Modelo básico del dominio (2) |
4. Refinar la interfaz de usuario |
5. Desarrollo ágil |
6. Herencia de superclases mapedas |
7. Herencia de entidades |
8. Herencia de vistas |
9. Propiedades Java |
10. Propiedades calculadas |
11. @DefaultValueCalculator en colecciones |
12. @Calculation y totales de colección |
13. @DefaultValueCalculator desde archivo |
14. Evolución del esquema manual |
15. Cálculo de valor por defecto multiusuario |
16. Sincronizar propiedades persistentes y calculadas |
17. Lógica desde la base de datos |
18. Validando con @EntityValidator |
19. Alternativas de validación |
20: Validación al borrar |
21. Anotación Bean Validation propia |
22. Llamada REST desde una validación |
23. Atributos en anotaciones |
24. Refinar el comportamiento predefinido |
25. Comportamiento y lógica de negocio |
26. Referencias y colecciones |
A. Arquitectura y filosofía |
B. Java Persistence API |
C. Anotaciones |
D. Pruebas automáticas
En la lección anterior vimos alternativas de validación al grabar. En esta lección vamos a ver como validar al borrar.
Si no te gustan los videos sigue las instrucciones a continuación.
Validar al borrar con @RemoveValidator
Las validaciones que hemos visto hasta ahora se hacen cuando la entidad se modifica, pero a veces es útil hacer la validación justo al borrar la entidad y usar la validación para vetar el borrado de la misma.
Vamos a modificar la aplicación para impedir que un usuario borre un pedido si éste tiene una factura asociada. Para hacer esto anota tu entidad
Pedido con
@RemoveValidator, como se muestra a continuación:
@RemoveValidator(com.tuempresa.facturacion.validadores.ValidadorBorrarPedido.class) // La clase con la validación
public class Pedido extends DocumentoComercial {
Ahora, antes de borrar un pedido la lógica de
ValidadorBorrarPedido se ejecuta y si la validación falla el pedido no se borra. Veamos el código de este validador:
package com.tuempresa.facturacion.validadores; // En el paquete 'validadores'
import com.tuempresa.facturacion.modelo.*;
import org.openxava.util.*;
import org.openxava.validators.*;
public class ValidadorBorrarPedido
implements IRemoveValidator { // Ha de implementar 'IRemoveValidator'
private Pedido pedido;
public void setEntity(Object entity) // La entidad a borrar se inyectará...
throws Exception // ...con este método antes de la validación
{
this.pedido = (Pedido) entity;
}
public void validate(Messages errors) // La lógica de validación
throws Exception
{
if (pedido.getFactura() != null) {
// Añadiendo mensajes a 'errors' la validación fallará y el
// borrado se abortará
errors.add("no_puede_borrar_pedido_con_factura");
}
}
}
La lógica de validación está en el método
validate(). Antes de llamarlo la entidad a validar es inyectada usando
setEntity(). Si se añaden mensajes al objeto
errors la validación fallará y la entidad no se borrará. Has de añadir el mensaje de error en el archivo
facturacion/src/main/resources/i18n/facturacion-messages_es.properties:
no_puede_borrar_pedido_con_factura=Pedido asociado a factura no puede ser eliminado
Ahora si intentas borrar un pedido con una factura asociada obtendrás un mensaje de error y el borrado no se producirá.
Puedes ver que usar un
@RemoveValidator no es difícil, pero es un poco verboso. Has de escribir una clase nueva solo para añadir un simple if. Examinemos una alternativa más breve.
Validar al borrar con un método de retrollamada
Vamos a probar otra forma más simple de hacer esta validación al borrar, moviendo la lógica de validación desde la clase validador a la misma entidad
Pedido, en este caso en un método
@PreRemove.
El primer paso es eliminar la clase
ValidadorBorrarPedido de tu proyecto. Además quita la anotación
@RemoveValidator de tu entidad
Pedido:
// @RemoveValidator(com.tuempresa.facturacion.validadores.ValidadorBorrarPedido.class) // Quitamos '@RemoveValidator'
public class Pedido extends DocumentoComercial {
Hemos quitado la validación. Añadámosla otra vez, pero ahora dentro de la misma clase
Pedido. Añade el método
validarPreBorrar() a la clase
Pedido, como se muestra a continuación:
@PreRemove
private void validarPreBorrar() {
if (factura != null) { // La lógica de validación
throw new javax.validation.ValidationException( // Lanza una excepción runtime
XavaResources.getString( // Para obtener un mensaje de texto
"no_puede_borrar_pedido_con_factura"));
}
}
Antes de borrar un pedido esta validación se efectuará, si falla se lanzará una
ValidationException. Puedes lanzar cualquier excepción runtime para abortar el borrado. Tan solo con un método dentro de la entidad tienes la validación hecha.
¿Cuál es la mejor forma de validar?
Has aprendido varias formas de hacer la validación sobre tus clases del modelo. ¿Cuál de ellas es la mejor? Todas ellas son opciones válidas. Depende de tus circunstancias y preferencias personales. Si tienes una validación que no es trivial y es reutilizable en varios puntos de tu aplicación, entonces usar un
@EntityValidator y
@RemoveValidator es una buena opción. Por otra parte, si quieres usar tu modelo fuera de OpenXava y sin JPA, entonces el uso de la validación en los
setters es mejor.
En nuestro caso particular hemos optado por
@AssertTrue para la validación “el pedido ha de estar servido para estar en una factura” y por
@PreRemove para la validación al borrar. Ya que son las alternativas más simples que funcionan.
Resumen
En esta lección has aprendido varias formas de hacer validación al borrar en una aplicación OpenXava. En la siguiente lección vas a ver como crear una anotación Bean Validation propia. ¡Esto puede llegar a ser muy útil!