Tabla de Contenidos
Objetos y Validaciones
En esta unidad vamos a realizar ejercicios relativos a las validaciones.
Ejercicio01
Siguiendo el Ejercicio01 de la unidad anterior , pero eliminado todo el código relativo a las consultas, vamos a realizar las siguientes tareas.
Validaciones
Siempre que sea posible deberemos definir las validaciones usando el estándar JSR 303: Bean Validation.
NIF
De la clase NIF
- Que el NIF sea único para cada seguro. Es decir que no puede haber 2 seguros con el mismo NIF
- Valida que el NIF tenga un tamaño de 9 caracteres.
- Valida que el NIF siga la expresión regular : “
[XYZ0-9][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]
” - Haz un método que valide la letra del NIF y cuyo mensaje sea “La letra del NIF no es válida”.Usa el siguiente algoritmo:
String letras = "TRWAGMYFPDXBNJZSQVHLCKE"; int valor; if (nif.startsWith("X")) { //Es un NIE valor=Integer.parseInt(nif.substring(1,nif.length()-1)); }else if (nif.startsWith("Y")) { //Es un NIE valor=10000000+Integer.parseInt(nif.substring(1,nif.length()-1)); }else if (nif.startsWith("Z")) { //Es un NIE valor=20000000+Integer.parseInt(nif.substring(1,nif.length()-1)); } else { //Es un NIF valor=Integer.parseInt(nif.substring(0,nif.length()-1)); } String letraCorrecta=""+letras.charAt(valor % 23); if (nif.endsWith(letraCorrecta)==true) { //El NIF es correcto } else { //El NIF es erroneo }
Enfermedades
De la clase Enfermedades
:
- No es posible que estén a
true
más de tres enfermedades. - Si está a
true
la propiedadalergia
la propiedadnombreAlergia
no puede sernull
ni ser únicamente espacios.
Coberturas
De la clase Coberturas
- Solo se puede ser
true
la propiedadfecundacionInVitro
si el sexo esMujer
.
Seguro
De la clase Seguro
:
- El campo
nif
debe ser válido - El campo
nombre
no puede estar vacio - El campo
ape1
no puede estar vacio - El campo
nif
debe ser válido - El campo
enfermedades
debe ser válido - El campo
coberturas
debe ser válido - El campo
edad
debe ser mayor que 0. - Si campo
edad
está entre 0 y 17 años deberá indicar que no es posible ser menor de edad para hacer un seguro. - El campo
sexo
no puede sernull
. - El campo
numHijos
no puede ser menor que 0. - El campo
numHijos
no puede ser mayor que 0 sicasado
esfalse
. (Es un poco machista pero es por hacer validaciones con distintos campos a la vez ). - El campo
embarazada
no puede sertrue
si el sexo esHombre
.
AsistenciaMedica
De la clase AsistenciaMedica
:
- El campo
breveDescripcion
no puede estar vacio. - El campo
lugar
no puede estar vacio. - El campo
explicacion
no puede estar vacio. - El campo
tipoAsistencia
no puede ser null. - El campo
fecha
no puede ser null. - El campo
hora
no puede ser null. - El campo
importe
no puede ser null. - El campo
importe
debe tener 10 dígitos enteros y 2 decimales. - El campo
importe
debe ser mayor que cero.
Todas
De todas las clases:
- Personaliza los mensajes de la anotación @NotNull para que en vez de ser “no puede ser null” sea “No puede estar vacío”.
Cambios en los métodos
Hasta ahora todas nuestras clases han tenido únicamente métodos de set/get
y los métodos de validación. Pero ésto nos puede llevar al antipatrón del modelo anémico. Con este antipatrón lo que hacemos es tener dominios sin lógica y toda ella se pone en una capa superior llamada “Capa de servicio (Service Layer)”.
Ya hemos cambiado un poco nuestro modelo para hacerlo menos anémico al añadirle todas las validaciones pero vayamos ahora más allá y organicemos los métodos de las clases para incluir más lógica en nuestras clases.
Todas
De todas las clases:
- No debería poder establecerse la clave primaria de ninguna clase. Es decir, si ya la genera Hibernate , ¿para qué hay un método
setId….
?. Debemos eliminarlos todos.Dejamos losgetId…
ya que son útiles para saber cuál es la clave primaria.
Al quitar estos métodos se generará un error de que no los encuentra. La solución a este problema es hacer que Hibernate acceda directamente a las propiedades sin usar los métodosget/set
( Usar el atributoaccess=“field”
que se explica en Fichero de mapeo ''.hbm.xml'' ). Ésto lo deberemos hacer en todas las propiedades de todos nuestras entidades ya que así seremos libres de quitar losget/set
que queramos.
NIF
De la clase NIF
:
- Añadir un método llamado
getNumero()
que nos retorna sólo el número del NIF. (En los NIE se debe incluir tambien su letra inicial). - Añadir un método llamado
getLetra()
que nos retorna sólo la letra final del NIF/NIE - Añadir un método llamado
boolean isNIE()
que nos retornetrue
si el NIF es un NIE. Sabemos que es un NIF si empiza por un número. Y es un NIE si empieza por alguna de las letras “X” , “Y” o “Z”.
Vemos cómo hemos alimentado 1) la clase NIF
que aparentemente no era muy útil hasta ahora. Es decir, hemos añadido lógica a nuestro modelo.
Seguro
La siguiente tarea a realizar es añadir un campo a la clase Seguro
para que calcule automáticamente la fecha de creación del seguro. Para ello deberemos incluir un “listener” para que rellene el campo.
Main
En la clase Main
deberemos añadir este código.
SimpleDateFormat sdfFecha = new SimpleDateFormat("dd/MM/yyyy"); sdfFecha.setLenient(false); SimpleDateFormat sdfHora = new SimpleDateFormat("HH:mm:ss"); sdfHora.setLenient(false); Seguro seguro = new Seguro("65234857A", "Santiago", "Sanz", "López", 23, Sexo.Hombre, false, 1, false, new Coberturas(false, true, false), new Enfermedades(true, false, true, false, null)); AsistenciaMedica asistenciaMedica1 = new AsistenciaMedica(seguro, "Golpe en el brazo", "Madrid", "Fractura del radio derecho de la mano debido a golpe contundente con el suelo. Se escayola el brazo", TipoAsistencia.Hospitalaria, sdfFecha.parse("31/12/2013"), sdfHora.parse("11:21:45"), new BigDecimal("700.31")); AsistenciaMedica asistenciaMedica2 = new AsistenciaMedica(seguro, "Fiebre alta", "Alzira", "El paciente presenta cuadro alto de fiabre con deficultad para respirar. Se recetan antibioticos.", TipoAsistencia.Ambulatoria, sdfFecha.parse("27/02/2013"), sdfHora.parse("12:34:16"), new BigDecimal("81.14")); seguro.getAsistenciasMedicas().add(asistenciaMedica1); seguro.getAsistenciasMedicas().add(asistenciaMedica2); session = sessionFactory.openSession(); try { session.beginTransaction(); session.save(seguro); session.getTransaction().commit(); } catch (javax.validation.ConstraintViolationException cve) { session.getTransaction().rollback(); System.out.println("No se ha podido insertar el seguro debido a los siguientes errores:"); for (ConstraintViolation constraintViolation : cve.getConstraintViolations()) { System.out.println("En el campo '" + constraintViolation.getPropertyPath() + "':" + constraintViolation.getMessage()); } } catch (org.hibernate.exception.ConstraintViolationException cve) { session.getTransaction().rollback(); System.out.println("No se ha podido insertar el seguro debido al siguiente error:"); System.out.println("El valor ya existe." + cve.getLocalizedMessage()); }
Ejercicio02 Optativo
Este ejercicio es optativo.
- Modifica el Ejercicio01 de esta misma unidad para hacer que al implementar el listener en la clase
Seguro
no se tenga ninguna referencia a clases , interfaces ,etc de Hibernate. Es decir que no haya referencia al interfaz PreInsertEventListener ni a nada más de Hibernate.