Herramientas de usuario

Herramientas del sitio


ejercicios:unidad06
no way to compare when less than two revisions

Diferencias

Muestra las diferencias entre dos versiones de la página.


ejercicios:unidad06 [2023/04/07 21:26] (actual) – creado - editor externo 127.0.0.1
Línea 1: Línea 1:
 +====== 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:
 +  * <code java>
 +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
 +
 +</code>
 +=== Enfermedades ===
 +De la clase ''Enfermedades'':
 +  * No es posible que estén a ''true'' más de tres enfermedades.
 +  * Si está a ''true'' la propiedad ''alergia'' la propiedad ''nombreAlergia'' no puede ser ''null'' ni ser únicamente espacios.
 +
 +=== Coberturas ===
 +De la clase ''Coberturas''
 +  * Solo se puede ser ''true'' la propiedad ''fecundacionInVitro'' si el sexo es ''Mujer''
 +
 +=== 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 ser ''null''.
 +  * El campo ''numHijos'' no puede ser menor que 0.
 +  * El campo ''numHijos'' no puede ser mayor que 0 si ''casado'' es ''false''. (Es un poco machista pero es por hacer validaciones con distintos campos a la vez :-( ).
 +  * El campo ''embarazada'' no puede ser ''true'' si el sexo es ''Hombre''
 +
 +
 +=== 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 [[http://martinfowler.com/bliki/AnemicDomainModel.html|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 los ''getId...'' 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étodos ''get/set'' ( Usar el atributo ''access="field"'' que se explica en  [[unidades:02_hibernate:02_entidad#fichero_de_mapeo_hbmxml|Fichero de mapeo ''.hbm.xml'']] ). Ésto lo deberemos hacer en todas las propiedades de todos nuestras entidades ya que así seremos libres de quitar los ''get/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 retorne ''true'' 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// (( lo contrario de estar anémico ))  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.
 +<code java>
 +        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());
 +        }
 +</code>
 +
 +===== 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 <javadoc h41>org.hibernate.event.spi.PreInsertEventListener|PreInsertEventListener</javadoc> ni a nada más de Hibernate.
 +
  
ejercicios/unidad06.txt · Última modificación: 2023/04/07 21:26 por 127.0.0.1