07 - Persistencia con JPA

El punto débil que dejó el hito 06 — stock reservado sin pedido cuando la persistencia falla — es el mejor argumento para este hito. Aplica el tema 05 — Persistencia: Spring JPA: la inversión de dependencias ya existe desde la partida — las interfaces de repositorio viven en domain —, así que lo que cambia es el mecanismo detrás de ellas: la persistencia JDBC se sustituye por JPA/Hibernate, repositorios de Spring Data y mapeos con MapStruct, sin tocar dominio, casos de uso, contrato ni API pública. La paginación a mano con JDBC también desaparece: Spring Data la resuelve.

Pieza Cambio en este hito
Persistencia DAO JDBC → entidades JPA y repositorios Spring Data, en cada módulo
Dominio Sin cambios: las interfaces de repositorio siguen definidas en domain
Paginación LIMIT/OFFSET a mano → Pageable/Page de Spring Data
Mapeos MapStruct entre entidades y modelos del dominio
Transacciones Crear y cancelar pedidos se vuelven atómicos
Pruebas Testcontainers: MariaDB real en las pruebas de persistencia
  • Dependencia Data JPA de Spring (el driver de MariaDB ya entró con la partida). El esquema lo sigue gestionando el init.sql: las entidades mapean contra él y no lo generan.
  • Entidades JPA para las tablas de cada módulo, con sus relaciones — el producto con su catálogo, el pedido con sus líneas — según las decisiones que muestra el tema 05.
  • Repositorios de Spring Data junto a las entidades: las consultas se derivan de la firma de sus métodos. La paginación del catálogo pasa a lo que ya trae — el Pageable entra y la Page devuelve el contenido y los metadatos que el contrato declara —: el recuento a mano del hito 04 desaparece.
  • Las implementaciones de las interfaces del dominio se reconstruyen sobre las piezas nuevas, y los mapeos entre entidades y modelos del dominio se declaran con MapStruct del modo que muestra el tema. El dominio sigue sin conocer JPA, MapStruct ni Spring: se comprueba en los imports de sus clases.
  • Crear un pedido pasa a ser una transacción: reservar todas las líneas y persistir el pedido comparten el mismo contexto y la misma base de datos; si una línea falla, la excepción hace rollback de todo — el stock queda como estaba y el pedido no se crea. La protección a mano del hito 06 desaparece.
  • Cancelar también: liberar el stock y cambiar el estado, atómicos.
La transacción cruza módulos porque escriben en la misma base de datos. Es el piso del tema 08: una operación auxiliar — enviar la factura, avisar de stock bajo — no debería entrar en esa transacción; de ahí los eventos.

Criterio del nivel: las pruebas del repositorio van contra la base de datos real del proyecto, no contra un sustituto. La decisión de la práctica: Testcontainers con la misma imagen de MariaDB del curso (fijada en la especificación).

  • Catálogo: guardar y recuperar mantiene el producto intacto — catálogo, precio y stock como corresponden; listar; borrar.
  • Paginación: el listado de un catálogo respeta tamaño, orden y totales, con los metadatos que Spring Data aporta.
  • Pedidos: guardar cabecera y líneas; recuperar el pedido con sus líneas y sus precios capturados.
  • Transacción: crear un pedido cuya segunda línea no tiene stock deja el catálogo sin cambios y sin pedido — la prueba integra ambos módulos sobre el contenedor.
  • Las pruebas anteriores no cambian: dominio sin base de datos, presentación con dobles, límites con sus verificaciones.
  • Ya no queda JDBC: todo acceso a datos pasa por las interfaces de repositorio del dominio, implementadas en persistence con JPA.
  • El listado paginado responde igual que en el hito 04, pero sin SQL de paginación escrito a mano.
  • El dominio no importa JPA, MapStruct ni Spring (comprobar con los imports y con las reglas ArchUnit).
  • Las pruebas de persistencia corren contra MariaDB en Testcontainers.
  • Un pedido con una línea imposible no deja nada a medias: transacción probada.
  • El contrato no cambia (sin subida de versión); commit y tag hito-07.

Siguiente hito: hito 08 — Login con JWT.

  • clase/daw/dws/1eval/practicas/p7.txt
  • Última modificación: 2026/10/28 13:32
  • por cesguiro