Neste artigo vamos complementar a aula do YouTube onde implementamos o cadastro de produtos com múltiplas categorias utilizando Spring Boot, JPA e DTOs. A proposta foi trabalhar um CRUD completo com relacionamento do tipo muitos-para-muitos (N:N) entre Produto e Categoria.
📺 Assista ao vídeo completo no YouTube: https://youtu.be/8PXIQ6L_WWM
Essa estrutura é muito comum em sistemas de e-commerce, catálogos ou marketplaces, onde um produto pode pertencer a várias categorias e vice-versa.
✨ O que foi implementado
- Entidade
Produtocom anotações@ManyToManye campos de auditoria (createdAt,updatedAt); - CRUD completo para
Produto(listar, buscar por id, salvar, atualizar, deletar); - Conversão de
ProdutoDTO→Produtocom população da lista de categorias; - Uso de
@Transactional,@CreationTimestamp,@UpdateTimestamp,Set<Categoria>; - Boas práticas com método
copyDtoToProduto(...)noService.
🔹 Relacionamento Produto x Categoria
Na entidade Produto, o relacionamento foi definido assim:
@ManyToMany
@JoinTable(name = "produto_categoria",
joinColumns = @JoinColumn(name = "produto_id"),
inverseJoinColumns = @JoinColumn(name = "categoria_id")
)
private Set<Categoria> categorias = new HashSet<>();
Esse mapeamento cria uma tabela associativa chamada produto_categoria, com as chaves estrangeiras produto_id e categoria_id.
🔄 Conversão DTO → Entidade
Criamos o método abaixo para copiar os dados do DTO para a entidade Produto:
private void copyDtoToProduto(ProdutoDTO dto, Produto produto) {
produto.setNome(dto.getNome());
produto.setDescricao(dto.getDescricao());
produto.setPreco(dto.getPreco());
produto.setImgUrl(dto.getImgUrl());
produto.getCategorias().clear();
for (CategoriaDTO categoriaDTO : dto.getCategorias()) {
Categoria categoria = categoriaRepository.getReferenceById(categoriaDTO.getId());
produto.getCategorias().add(categoria);
}
}
Esse método é usado tanto em salvarProduto quanto em atualizarProduto, garantindo consistência na manipulação dos dados.
🚀 Testando a API com Postman
POST – Cadastrando Produto com Categorias
Endpoint: POST http://localhost:8080/produto
{
"nome": "Casa de Alqueria D.O. Valle Central Carménère 2024",
"preco": 42.50,
"descricao": "Casa de Alqueria é uma linha de vinhos jovens, amigáveis e descomplicados elaborada pela Cremaschi Barriga...",
"imgUrl": "",
"categorias": [
{ "id": 1 },
{ "id": 5 }
]
}
Esse comando cria um produto e associa às categorias com id = 1 e id = 5.
PUT – Atualizando Produto com Categorias
Endpoint: PUT http://localhost:8080/produto/13
{
"nome": "Casa de Alqueria D.O. Valle Central Carménère 2024",
"preco": 18.99,
"descricao": "Casa de Alqueria é uma linha de vinhos jovens, amigáveis e descomplicados elaborada pela Cremaschi Barriga...",
"imgUrl": "",
"categorias": [
{ "id": 1 },
{ "id": 5 }
]
}
Esse comando atualiza completamente o produto com ID 13 e substitui as categorias.
⚠️ O método
PUTé destrutivo: ele limpa todas as categorias anteriores e substitui pelas informadas.
📊 Conclusão
Esse foi mais um passo importante na evolução do nosso backend com Spring Boot, mostrando como lidar com relacionamentos N:N de forma segura, controlada e performável.
Na próxima aula, podemos evoluir para:
- Listagem com filtro por categoria
- Busca por nome com
LIKE - Validação com
@Valid - E claro, testes automatizados!
Continue acompanhando nossa trilha e bons códigos! 🚀