Practica 1

parent d554e340
Showing with 366 additions and 0 deletions
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36" version="28.2.3">
<diagram id="uml1" name="UML Practica 1">
<mxGraphModel dx="1904" dy="1050" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Usuario" value="Usuario&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#dae8fc;" parent="1" vertex="1">
<mxGeometry x="465" y="70" width="170" height="220" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-3" value="id: Long&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;apellidos: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;nombre: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;fechaNacimiento: LocalDate&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;direccion: Direccion&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;telefono: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;email: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;login: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;claveHash: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;&lt;div style=&quot;&quot;&gt;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;rol: RolUsuario&lt;/span&gt;&lt;/div&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="Usuario">
<mxGeometry y="40" width="170" height="180" as="geometry" />
</mxCell>
<mxCell id="TipoIncidencia" value="TipoIncidencia&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#e1d5e7;" parent="1" vertex="1">
<mxGeometry x="720" y="100" width="130" height="120" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-6" value="id: Long&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;nombre: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;descripcion: String" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="TipoIncidencia">
<mxGeometry y="40" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="Incidencia" value="Incidencia&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#ffe6cc;" parent="1" vertex="1">
<mxGeometry x="450" y="450" width="200" height="170" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-10" value="id: Long&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;fecha: LocalDateTime&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;descripcion: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;direccion: Direccion&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;ubicacionGPS: CoordenadaGPS&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;estado: EstadoIncidencia" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="Incidencia">
<mxGeometry y="40" width="200" height="130" as="geometry" />
</mxCell>
<mxCell id="Direccion" value="Direccion&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#d5e8d4;" parent="1" vertex="1">
<mxGeometry x="775" y="270" width="200" height="140" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-9" value="calle: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;numero: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;ciudad: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;provincia: String&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;cp: String" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="Direccion">
<mxGeometry y="40" width="110" height="100" as="geometry" />
</mxCell>
<mxCell id="CoordenadaGPS" value="CoordenadaGPS&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#fff2cc;" parent="1" vertex="1">
<mxGeometry x="810" y="535" width="200" height="100" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-11" value="latitud: double&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;longitud: double" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="CoordenadaGPS">
<mxGeometry y="40" width="110" height="60" as="geometry" />
</mxCell>
<mxCell id="EstadoIncidencia" value="&lt;&lt;enum&gt;&gt;&#xa;EstadoIncidencia" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#f8cecc;" parent="1" vertex="1">
<mxGeometry x="120" y="490" width="180" height="120" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-7" value="&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;PENDIENTE&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;EN_EVALUACION&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;RESUELTA" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="EstadoIncidencia">
<mxGeometry y="40" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="RolUsuario" value="&lt;&lt;enum&gt;&gt;&#xa;RolUsuario&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#f8cecc;" parent="1" vertex="1">
<mxGeometry x="465" y="690" width="180" height="100" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-8" value="ADMIN&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;NORMAL" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="RolUsuario">
<mxGeometry y="40" width="70" height="60" as="geometry" />
</mxCell>
<mxCell id="ServicioUsuarios" value="ServicioUsuarios" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#cce5ff;" parent="1" vertex="1">
<mxGeometry x="84" y="830" width="330" height="170" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-1" value="+ registrar(datos: Usuario): Usuario&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ actualizar(datos: Usuario): Usuario&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ autenticar(login: String, clave: String): Usuario&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ cambiarClave(usuarioId: Long, nuevaClave: String): void" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="ServicioUsuarios">
<mxGeometry y="40" width="330" height="130" as="geometry" />
</mxCell>
<mxCell id="ServicioIncidencias" value="ServicioIncidencias&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#cce5ff;" parent="1" vertex="1">
<mxGeometry x="470" y="830" width="460" height="180" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-2" value="+ crearIncidencia(autorId: Long, datos: Incidencia): Incidencia&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ listarMisIncidencias(autorId: Long): List&amp;lt;Incidencia&amp;gt;&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ buscar(tipo: String, estado: EstadoIncidencia): List&amp;lt;Incidencia&amp;gt;&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ borrarSiPendiente(autorId: Long, incidenciaId: Long): void&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ adminCambiarEstado(incidenciaId: Long, nuevoEstado: EstadoIncidencia): void&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ adminBorrar(incidenciaId: Long): void" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="ServicioIncidencias">
<mxGeometry y="40" width="460" height="140" as="geometry" />
</mxCell>
<mxCell id="ServicioTiposIncidencia" value="ServicioTiposIncidencia&#xa;" style="shape=swimlane;childLayout=stackLayout;horizontal=1;rounded=1;strokeColor=#000000;fillColor=#cce5ff;" parent="1" vertex="1">
<mxGeometry x="970" y="830" width="330" height="140" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-12" value="+crear(nombre: String, descripcion: String): TipoIncidencia&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ eliminar(id: Long): void&lt;br style=&quot;padding: 0px; margin: 0px;&quot;&gt;+ listar(): List&amp;lt;TipoIncidencia&amp;gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="ServicioTiposIncidencia">
<mxGeometry y="40" width="330" height="100" as="geometry" />
</mxCell>
<mxCell id="rel1" style="endArrow=block;endFill=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="Incidencia" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="440" y="390" as="sourcePoint" />
<mxPoint x="550" y="290" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-13" value="&lt;font style=&quot;font-size: 14px;&quot;&gt;1&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="520" y="295" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-14" value="&lt;font style=&quot;font-size: 18px;&quot;&gt;*&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="520" y="415" width="30" height="40" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-15" value="&lt;font style=&quot;font-size: 14px;&quot;&gt;1&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="730" y="250" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-16" value="&lt;font style=&quot;font-size: 18px;&quot;&gt;*&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="600" y="415" width="30" height="40" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-17" value="" style="endArrow=diamondThin;endFill=1;endSize=24;html=1;rounded=0;entryX=1.002;entryY=0.225;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.979;exitY=1.026;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="DnhSClKIzYs1deEeSmZl-9" target="DnhSClKIzYs1deEeSmZl-10">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="610" y="380" as="sourcePoint" />
<mxPoint x="770" y="380" as="targetPoint" />
<Array as="points">
<mxPoint x="883" y="470" />
<mxPoint x="883" y="520" />
<mxPoint x="750" y="518" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-18" value="&lt;font style=&quot;font-size: 14px;&quot;&gt;1&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="850" y="408" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-19" value="&lt;font style=&quot;font-size: 14px;&quot;&gt;1&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="655" y="488" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-20" value="" style="endArrow=diamondThin;endFill=1;endSize=24;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="650" y="583" as="sourcePoint" />
<mxPoint x="810" y="583" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-26" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.613;exitY=-0.005;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.309;entryY=0.99;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="Incidencia" target="DnhSClKIzYs1deEeSmZl-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="595" y="430" as="sourcePoint" />
<mxPoint x="748.7850467289722" y="230" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-28" value="&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="300" y="549" as="sourcePoint" />
<mxPoint x="450" y="549.44" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="DnhSClKIzYs1deEeSmZl-32" value="&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;exitX=0.462;exitY=-0.019;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="RolUsuario">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="510" y="660" as="sourcePoint" />
<mxPoint x="548" y="620" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ayto</groupId>
<artifactId>incidencias-backend</artifactId>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
<spring-boot.version>3.3.3</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type><scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>10</source>
<target>10</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.ayto.incidencias.dominio;
public class CoordenadaGPS {
private Double latitud;
private Double longitud;
public Double getLatitud() { return latitud; }
public void setLatitud(Double latitud) { this.latitud = latitud; }
public Double getLongitud() { return longitud; }
public void setLongitud(Double longitud) { this.longitud = longitud; }
}
package com.ayto.incidencias.dominio;
public class Direccion {
private String calle;
private String numero;
private String ciudad;
private String provincia;
private String cp;
public String getCalle() { return calle; }
public void setCalle(String calle) { this.calle = calle; }
public String getNumero() { return numero; }
public void setNumero(String numero) { this.numero = numero; }
public String getCiudad() { return ciudad; }
public void setCiudad(String ciudad) { this.ciudad = ciudad; }
public String getProvincia() { return provincia; }
public void setProvincia(String provincia) { this.provincia = provincia; }
public String getCp() { return cp; }
public void setCp(String cp) { this.cp = cp; }
}
\ No newline at end of file
package com.ayto.incidencias.dominio;
public enum EstadoIncidencia {
PENDIENTE,
EVALUACION,
RESUELTA
}
package com.ayto.incidencias.dominio;
import java.time.LocalDateTime;
public class Incidencia {
private Long id;
private TipoIncidencia tipo;
private LocalDateTime fecha;
private String descripcion;
private Direccion direccion;
private CoordenadaGPS ubicacionGPS;
private EstadoIncidencia estado;
private Usuario autor;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public TipoIncidencia getTipo() { return tipo; }
public void setTipo(TipoIncidencia tipo) { this.tipo = tipo; }
public LocalDateTime getFecha() { return fecha; }
public void setFecha(LocalDateTime fecha) { this.fecha = fecha; }
public String getDescripcion() { return descripcion; }
public void setDescripcion(String descripcion) { this.descripcion = descripcion; }
public Direccion getDireccion() { return direccion; }
public void setDireccion(Direccion direccion) { this.direccion = direccion; }
public CoordenadaGPS getUbicacionGPS() { return ubicacionGPS; }
public void setUbicacionGPS(CoordenadaGPS ubicacionGPS) { this.ubicacionGPS = ubicacionGPS; }
public EstadoIncidencia getEstado() { return estado; }
public void setEstado(EstadoIncidencia estado) { this.estado = estado; }
public Usuario getAutor() { return autor; }
public void setAutor(Usuario autor) { this.autor = autor; }
}
\ No newline at end of file
package com.ayto.incidencias.dominio;
public enum RolUsuario {
ADMIN,
NORMAL
}
package com.ayto.incidencias.dominio;
public class TipoIncidencia {
private Long id;
private String nombre;
private String descripcion;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getNombre() { return nombre; }
public void setNombre(String nombre) { this.nombre = nombre; }
public String getDescripcion() { return descripcion; }
public void setDescripcion(String descripcion) { this.descripcion = descripcion; }
}
\ No newline at end of file
package com.ayto.incidencias.dominio;
import java.time.LocalDate;
import java.util.concurrent.atomic.AtomicLong;
public class Usuario {
private static final AtomicLong SEQ = new AtomicLong(0);
private Long id = SEQ.incrementAndGet();
private String apellidos;
private String nombre;
private LocalDate fechaNacimiento;
private String direccion;
private String telefono;
private String email;
private String login;
private String claveHash;
private RolUsuario rol = RolUsuario.NORMAL;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getApellidos() { return apellidos; }
public void setApellidos(String apellidos) { this.apellidos = apellidos; }
public String getNombre() { return nombre; }
public void setNombre(String nombre) { this.nombre = nombre; }
public LocalDate getFechaNacimiento() { return fechaNacimiento; }
public void setFechaNacimiento(LocalDate fechaNacimiento) { this.fechaNacimiento = fechaNacimiento; }
public String getDireccion() { return direccion; }
public void setDireccion(String direccion) { this.direccion = direccion; }
public String getTelefono() { return telefono; }
public void setTelefono(String telefono) { this.telefono = telefono; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getLogin() { return login; }
public void setLogin(String login) { this.login = login; }
public String getClaveHash() { return claveHash; }
public void setClaveHash(String claveHash) { this.claveHash = claveHash; }
public RolUsuario getRol() { return rol; }
public void setRol(RolUsuario rol) { this.rol = rol; }
}
package com.ayto.incidencias.repo;
import com.ayto.incidencias.dominio.Incidencia;
import java.util.*;
public interface IncidenciaRepo {
Incidencia save(Incidencia i);
Optional<Incidencia> findById(Long id);
void delete(Long id);
List<Incidencia> findByAutor(Long usuarioId);
List<Incidencia> findAll();
}
\ No newline at end of file
package com.ayto.incidencias.repo;
import com.ayto.incidencias.dominio.TipoIncidencia;
import java.util.*;
public interface TipoIncidenciaRepo {
TipoIncidencia save(TipoIncidencia t);
void delete(Long id);
boolean existsByNombre(String nombre);
Optional<TipoIncidencia> findById(Long id);
List<TipoIncidencia> findAll();
}
package com.ayto.incidencias.repo;
import com.ayto.incidencias.dominio.Usuario;
import java.util.Optional;
public interface UsuarioRepo {
Usuario save(Usuario u);
Optional<Usuario> findByLogin(String login);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment