Commit fd618113 by Antonio Rueda

Mejora de la eficiencia de las búsquedas de movimientos.

Carga y operaciones en cascada en relación cliente-cuentas
parent 9ca0772c
...@@ -65,7 +65,7 @@ public class Cliente implements Serializable { ...@@ -65,7 +65,7 @@ public class Cliente implements Serializable {
List<Tarjeta> tarjetas; List<Tarjeta> tarjetas;
/** Cuentas asociadas al cliente */ /** Cuentas asociadas al cliente */
@OneToMany(mappedBy="titular") @OneToMany(mappedBy="titular", fetch = FetchType.EAGER, cascade=CascadeType.ALL)
List<Cuenta> cuentas; List<Cuenta> cuentas;
public Cliente() { public Cliente() {
......
...@@ -33,13 +33,6 @@ public class RepositorioClientes { ...@@ -33,13 +33,6 @@ public class RepositorioClientes {
em.persist(cliente); em.persist(cliente);
} }
public void nuevaTarjeta(Cliente cliente, Tarjeta tarjeta) {
em.persist(tarjeta);
cliente = em.merge(cliente);
cliente.nuevaTarjeta(tarjeta);
}
public void actualizar(Cliente cliente) { public void actualizar(Cliente cliente) {
em.merge(cliente); em.merge(cliente);
} }
......
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package es.ujaen.dae.ujacoin.repositorios;
import es.ujaen.dae.ujacoin.entidades.Cuenta;
import es.ujaen.dae.ujacoin.entidades.movimientos.Movimiento;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.List;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author ajrueda
*/
@Repository
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class RepositorioMovimientos {
@PersistenceContext
EntityManager em;
public List<Movimiento> buscarDesdeFechaHora(Cuenta c, LocalDateTime fechaHora) {
return em.createQuery("select m from Cuenta c join c.movimientos m where c = ?1 and m.fechaHora >= ?2")
.setParameter(1, c)
.setParameter(2, fechaHora)
.getResultList();
}
public List<Movimiento> buscarDesdeHastaFechaHora(Cuenta c, LocalDateTime fechaHoraDesde, LocalDateTime fechaHoraHasta) {
return em.createQuery("select m from Cuenta c join c.movimientos m where c.num = ?1 and m.fechaHora between ?2 and ?3")
.setParameter(1, c.getNum())
.setParameter(2, fechaHoraDesde)
.setParameter(3, fechaHoraHasta)
.getResultList();
}
}
\ No newline at end of file
...@@ -20,6 +20,7 @@ import jakarta.validation.constraints.NotNull; ...@@ -20,6 +20,7 @@ import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive; import jakarta.validation.constraints.Positive;
import es.ujaen.dae.ujacoin.repositorios.RepositorioClientes; import es.ujaen.dae.ujacoin.repositorios.RepositorioClientes;
import es.ujaen.dae.ujacoin.repositorios.RepositorioCuentas; import es.ujaen.dae.ujacoin.repositorios.RepositorioCuentas;
import es.ujaen.dae.ujacoin.repositorios.RepositorioMovimientos;
import jakarta.validation.constraints.Past; import jakarta.validation.constraints.Past;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
...@@ -44,6 +45,10 @@ public class ServicioUjaCoin { ...@@ -44,6 +45,10 @@ public class ServicioUjaCoin {
@Autowired @Autowired
RepositorioCuentas repositorioCuentas; RepositorioCuentas repositorioCuentas;
@Autowired
RepositorioMovimientos repositorioMovimientos;
public ServicioUjaCoin() { public ServicioUjaCoin() {
} }
...@@ -57,12 +62,10 @@ public class ServicioUjaCoin { ...@@ -57,12 +62,10 @@ public class ServicioUjaCoin {
throw new ClienteYaRegistrado(); throw new ClienteYaRegistrado();
} }
Cuenta cuenta = new Cuenta(generarNumCuenta(), cliente);
cliente.nuevaCuenta(cuenta);
repositorioClientes.guardar(cliente); repositorioClientes.guardar(cliente);
// Crear y registrar cuenta
Cuenta cuenta = crearCuenta(cliente);
repositorioCuentas.guardar(cuenta);
return cuenta; return cuenta;
} }
...@@ -77,8 +80,6 @@ public class ServicioUjaCoin { ...@@ -77,8 +80,6 @@ public class ServicioUjaCoin {
Optional<Cliente> clienteLogin = repositorioClientes.buscar(dni) Optional<Cliente> clienteLogin = repositorioClientes.buscar(dni)
.filter((cliente)->cliente.claveValida(clave)); .filter((cliente)->cliente.claveValida(clave));
// Asegurarnos de que se devuelve el cliente con los datos precargados
clienteLogin.ifPresent(c -> c.verCuentas().size());
return clienteLogin; return clienteLogin;
} }
...@@ -90,8 +91,9 @@ public class ServicioUjaCoin { ...@@ -90,8 +91,9 @@ public class ServicioUjaCoin {
public Cuenta crearCuenta(@NotBlank String dni) { public Cuenta crearCuenta(@NotBlank String dni) {
Cliente cliente = repositorioClientes.buscar(dni).orElseThrow(ClienteNoRegistrado::new); Cliente cliente = repositorioClientes.buscar(dni).orElseThrow(ClienteNoRegistrado::new);
Cuenta cuenta = crearCuenta(cliente); Cuenta cuenta = new Cuenta(generarNumCuenta(), cliente);
repositorioCuentas.guardar(cuenta); cliente.nuevaCuenta(cuenta);
repositorioClientes.actualizar(cliente);
return cuenta; return cuenta;
} }
...@@ -197,11 +199,14 @@ public class ServicioUjaCoin { ...@@ -197,11 +199,14 @@ public class ServicioUjaCoin {
* @return la lista de los movimientos entre las fechas indicadas * @return la lista de los movimientos entre las fechas indicadas
*/ */
@Transactional @Transactional
List<Movimiento> listarMovimientosCuentaDesdeHasta(@NotBlank String numCuenta, @Past LocalDateTime fechaHoraDesde, @Past LocalDateTime fechaHoraHasta) { List<Movimiento> listarMovimientosCuentaDesdeHasta(@NotBlank String numCuenta, @Past LocalDateTime fechaHoraDesde, LocalDateTime fechaHoraHasta) {
Cuenta cuenta = repositorioCuentas.buscar(numCuenta) Cuenta cuenta = repositorioCuentas.buscar(numCuenta)
.orElseThrow(CuentaNoRegistrada::new); .orElseThrow(CuentaNoRegistrada::new);
return cuenta.listarMovimientosDesdeHasta(fechaHoraDesde, fechaHoraHasta); // Ineficiente
// return cuenta.listarMovimientosDesdeHasta(fechaHoraDesde, fechaHoraHasta);
return repositorioMovimientos.buscarDesdeHastaFechaHora(cuenta, fechaHoraDesde, fechaHoraHasta);
} }
/** /**
...@@ -211,15 +216,18 @@ public class ServicioUjaCoin { ...@@ -211,15 +216,18 @@ public class ServicioUjaCoin {
* @return el listado de movimientos * @return el listado de movimientos
*/ */
@Transactional @Transactional
public List<Movimiento> listarMovimientosDesde(@NotBlank String numCuenta, @Past LocalDateTime fechaHoraDesde) { public List<Movimiento> listarMovimientosCuentaDesde(@NotBlank String numCuenta, @Past LocalDateTime fechaHoraDesde) {
Cuenta cuenta = repositorioCuentas.buscar(numCuenta) Cuenta cuenta = repositorioCuentas.buscar(numCuenta)
.orElseThrow(CuentaNoRegistrada::new); .orElseThrow(CuentaNoRegistrada::new);
return cuenta.listarMovimientosDesde(fechaHoraDesde); // Ineficiente
// return cuenta.listarMovimientosDesde(fechaHoraDesde);
return repositorioMovimientos.buscarDesdeFechaHora(cuenta, fechaHoraDesde);
} }
// Crear una cuenta para el cliente indicado con un número no asignado // Crear una cuenta para el cliente indicado con un número no asignado
private Cuenta crearCuenta(Cliente cliente) { private String generarNumCuenta() {
// Generar número de cuenta de 10 dígitos aleatorio y no usado previamente // Generar número de cuenta de 10 dígitos aleatorio y no usado previamente
String numCuenta; String numCuenta;
long min = 1000000000L; long min = 1000000000L;
...@@ -228,11 +236,6 @@ public class ServicioUjaCoin { ...@@ -228,11 +236,6 @@ public class ServicioUjaCoin {
numCuenta = Long.toString(min + (long) (Math.random() * (max - min))); numCuenta = Long.toString(min + (long) (Math.random() * (max - min)));
} while (repositorioCuentas.buscar(numCuenta).isPresent()); } while (repositorioCuentas.buscar(numCuenta).isPresent());
Cuenta cuenta = new Cuenta(numCuenta, cliente); return numCuenta;
// No es necesario al ser una relación bidireccional gestionada por JPA
// cliente.nuevaCuenta(cuenta);
return cuenta;
} }
} }
...@@ -154,7 +154,7 @@ public class ServicioUjaCoinTest { ...@@ -154,7 +154,7 @@ public class ServicioUjaCoinTest {
// Realizar ingreso y comprobar estado de la cuenta // Realizar ingreso y comprobar estado de la cuenta
servicioUjaCoin.ingreso(cuentas.get(0).getNum(), tarjeta.getNum(), 1000); servicioUjaCoin.ingreso(cuentas.get(0).getNum(), tarjeta.getNum(), 1000);
List<Movimiento> movimientos = servicioUjaCoin.listarMovimientosDesde(cuentas.get(0).getNum(), LocalDateTime.MIN); List<Movimiento> movimientos = servicioUjaCoin.listarMovimientosCuentaDesdeHasta(cuentas.get(0).getNum(), LocalDateTime.now().minusDays(1), LocalDateTime.now().plusHours(1));
Assertions.assertThat(movimientos).hasSize(1); Assertions.assertThat(movimientos).hasSize(1);
Assertions.assertThat(movimientos.get(0)).isInstanceOf(Ingreso.class); Assertions.assertThat(movimientos.get(0)).isInstanceOf(Ingreso.class);
Assertions.assertThat(movimientos.get(0).getImporte()).isEqualTo(1000); Assertions.assertThat(movimientos.get(0).getImporte()).isEqualTo(1000);
...@@ -204,13 +204,13 @@ public class ServicioUjaCoinTest { ...@@ -204,13 +204,13 @@ public class ServicioUjaCoinTest {
cuentaDestino = servicioUjaCoin.verCuentas(cliente2.getDni()).get(0); cuentaDestino = servicioUjaCoin.verCuentas(cliente2.getDni()).get(0);
// Listar movimientos de la cuenta origen // Listar movimientos de la cuenta origen
List<Movimiento> movimientos = servicioUjaCoin.listarMovimientosDesde(cuentaOrigen.getNum(), LocalDateTime.MIN); List<Movimiento> movimientos = servicioUjaCoin.listarMovimientosCuentaDesde(cuentaOrigen.getNum(), LocalDateTime.now().minusDays(1));
Assertions.assertThat(movimientos).hasSize(2); Assertions.assertThat(movimientos).hasSize(2);
Assertions.assertThat(movimientos.get(1)).isInstanceOf(TransferenciaEmitida.class); Assertions.assertThat(movimientos.get(1)).isInstanceOf(TransferenciaEmitida.class);
Assertions.assertThat(cuentaOrigen.getSaldo()).isEqualTo(500); Assertions.assertThat(cuentaOrigen.getSaldo()).isEqualTo(500);
// Listar movimientos de la cuenta destino // Listar movimientos de la cuenta destino
movimientos = servicioUjaCoin.listarMovimientosDesde(cuentaDestino.getNum(), LocalDateTime.MIN); movimientos = servicioUjaCoin.listarMovimientosCuentaDesde(cuentaDestino.getNum(), LocalDateTime.now().minusDays(1));
Assertions.assertThat(movimientos).hasSize(1); Assertions.assertThat(movimientos).hasSize(1);
Assertions.assertThat(movimientos.get(0)).isInstanceOf(TransferenciaRecibida.class); Assertions.assertThat(movimientos.get(0)).isInstanceOf(TransferenciaRecibida.class);
Assertions.assertThat(cuentaDestino.getSaldo()).isEqualTo(500); Assertions.assertThat(cuentaDestino.getSaldo()).isEqualTo(500);
......
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