Série: Recolocação e teste prático Java

Episódio 04: Da memória ao banco: persistindo veículos com JPA, H2 e Flyway

Episódio 04: Persistência

Estado que não some quando o request termina

Persistência é quando a API deixa de ser demonstração de request e passa a guardar estado. H2 em memória facilita a vida do avaliador, mas o PDF também pede migrations: estrutura explícita, não improviso.

Na visão geral, a API deixa de ser caixa preta: estado relacional e console H2 entram na narrativa de validação:

Visão geral
API de veículos Base relacional
(H2)
Avaliador
(console SQL)

Transparência: o avaliador confere linhas após um POST — o sistema não é uma caixa preta.

O problema por trás da etapa

A camada Infra concentra datasource, JPA, H2, migrations e implementações de repositório. Web e Application não precisam saber se o banco é H2 ou outro mecanismo — precisam de operações confiáveis de salvar, buscar, listar e remover.

Configurar JDBC, console H2 para inspeção, Flyway em db/migration, JPA validando schema contra migrations: execução previsível e mensagem clara quando algo desalinha.

Nos blocos de execução, Flyway e Hibernate partilham o processo; o schema é contrato versionado em SQL:

O que corre na máquina
Spring Boot
(JPA + Flyway)
H2
(schema versionado)

Flyway e Hibernate partilham o mesmo processo; o contrato do schema é ficheiro SQL versionado.

A decisão técnica

A migration inicial cria tabela alinhada ao domínio: colunas coerentes com validação de entrada; tamanhos compatíveis com limites dos DTOs. Desalinhamento entre coluna e @Size é bug silencioso em produção e “sinal amarelo” em banca.

Spring Data JPA pode ser usado diretamente na aplicação ou atrás de adapter fino — escolha proporcional ao tamanho do teste. Listagem paginada: Pageable e Page na consulta, com responsabilidades repartidas: Web recebe parâmetros, Application orquestra, Infra executa a query.

A Infra decompõe-se em blocos técnicos — repositório, migrations, config e mapeamento — sem “explodir” queries no controller:

Componentes de infraestrutura
VeiculoRepository
(Spring Data)
Flyway
V1__… .sql
DataSource / JPA
config
Mapeamento ORM
entidade ↔ tabela

Consultas paginadas nascem aqui; a Web só repassa page/size — a query não “explode” no controller.

Implementando com critério

Veículo inexistente: repositório retorna vazio; a aplicação decide exceção ou resultado; a Web traduz para HTTP 404. Cada camada fala sua língua. No manual de arranque (README.md), registar URL, utilizador e senha do console H2 permite ao avaliador ver linhas após um POST no Swagger — detalhe pequeno, grande confiança.

Na organização do código, migration, entidade, repositório e application.yml são o rasto que o avaliador segue em caso de desalinhamento DTO ↔ coluna:

Detalhe no código
db/migration/V1__… VeiculoEntity + @Entity VeiculoJpaRepository application.yml
datasource + jpa + flyway

Nomes e ficheiros que o avaliador procura primeiro quando suspeita de desalinhamento DTO ↔ coluna.

Fechamento da etapa

Ao final: Flyway aplicando migration, Hibernate mapeando entidade, H2 acessível, repositórios prontos para os casos de uso. Erros de migration ou mapeamento devem aparecer cedo — melhor agora do que na hora da demo.

No próximo episódio, damos vida aos fluxos na camada Application.

Como defender essa etapa

Defenda persistência como fronteira: Flyway torna schema auditável; H2 console é transparência; paginação nasce no repositório sem controller engolido por Pageable.

Reflexão final: Banco em memória não é desculpa para contrato vago — migrations são prova de maturidade.


Nota: Cenário anonimizado; série de insights técnicos reutilizáveis.

Christian Mulato
Engenheiro Construtor

© 2026 Christian Mulato. Todos os direitos reservados.