O que você precisa saber sobre entidades no desenvolvimento
Entidade é um conceito que aparece em praticamente todo projeto de software que lida com dados persistentes. Na prática, é uma classe ou estrutura que representa um objeto do domínio — uma pessoa, um pedido, um produto, algo que existe no mundo real e precisa ser guardado no banco de dados. O conceito vem originalmente dos diagramas Entidade-Relacionamento, mas hoje ele se espalhou para ORMs, microserviços, APIs e arquiteturas hexagonais. O que são entidades varia dependendo da camada em que você as usa. Em um sistema legado com Doctrine, uma entidade é um mapeamento direto de tabela. Em DDD, uma entidade é algo com identidade própria que carrega comportamento, não apenas dados. A diferença importa bastante.
o que são entidades e como elas funcionam no dia a dia
Num projeto típico com PHP e Doctrine, por exemplo, você declara uma classe com anotações ou atributos, define os campos, relacionamentos e o ORM gera o SQL. Um campo como $id com atributo Identificador vira a chave primária. Relações como ManyToMany exigem uma tabela intermediária que o gerador cria automaticamente. Parece simples até você precisar mudar isso depois. Eu trabalhava num sistema de e-commerce onde a entidade Pedido tinha uma relação ManyToMany com Produto. Tudo funcionava até o momento em que precisámos adicionar um campo quantidade na tabela intermediária — o Doctrine não suporta campos extras diretamente nessa relação. A solução foi criar uma entidade separada para o item do pedido, PedidoItem, e transformar a ManyToMany em duas relações ManyToOne. Isso adicionou quatro classes novas, migrações extras e aproximadamente dois dias de trabalho que eu já teria evitado se tivesse pensado nisso desde o início.
O ponto mais ignorado por iniciantes é que entidade não é o mesmo que DTO, Value Object ou Agregado. Entidade tem identidade. Dois objetos com os mesmos dados são diferentes se os IDs forem diferentes. Valor muda com base nos campos, não no ID. Misturar esses conceitos leva a bugs chatos que aparecem só em produção. Outro detalhe que ninguém ensina: persistir entidades puro pelo banco é lento quando o número cresce. Num projeto meu com mais de 200 mil pedidos, queries de busca filtrando por múltiplos campos das entidades simplesmente travavam. A solução prática foi separar um Read Model com tabelas normalizadas para consulta, enquanto a escrita continuava usando as entidades normais. Isso reduziu o tempo médio de resposta de query de leitura de cerca de 800ms para 45ms.
Existem ferramentas que ajudam a lidar com entidades de forma mais orgânica. ODoctrine ORM para PHP, Sequelize para Node, SQLAlchemy para Python, prisma.io para projetos TypeScript — cada um com suas armadilhas específicas. A maioria dos iniciantes escolhe a ferramenta errada para o problema certo porque foca na sintaxe bonita em vez de entender o padrão por baixo.
👉 Clique no botão abaixo para saber mais sobre o assunto!
problemas comuns que ninguém menciona
Entidades viram lixo quando ninguém disciplina o ciclo de vida delas. Você cria uma, passa ela adiante por cinco camadas, alguém muda um campo, salva sem chamar flush adequadamente, e o banco fica inconsistentes. Isso acontece muito em projetos pequenos onde ainda não existe uma camada de serviço bem definida. Também é comum tentar usar entidades como se fossem requisições HTTP. Criar um endpoint que recebe dados e passa direto para o EntityManager é pedir para o código quebrar quando o formato da requisição mudar. O padrão correto é transformar a entrada num DTO, validar, transformar na entidade, persistir. Mais trabalho no início, menos dor de cabeça depois.
Performance é outro ponto onde entidade errada custa caro. Cada entidade carregada com fetchAll() ou sem lazy loading ativo pode disparar N+1 queries silenciosamente. Um SELECT principal e dezenas de SELECTs secundários para carregar relacionamentos. Ferramentas como o Doctrine DebugBundle ou ologger do Sequelize ajudam a identificar isso, mas só se você ativar o log de queries.
quando não usar entidades
Existem cenários onde entidades são overkill. Se o seu sistema é basicamente CRUD simples com poucas regras de negócio, um mapeamento direto entre tabela e classe pode ser suficiente sem a complexidade de um framework ORM completo. Scripts de migração direta com PDO ou even às vezes resolvem mais rápido do que configurar uma entidade completa. Sistemas altamente transacionais com milhões de writes por segundo também sofrem com a abstração de entidades. O overhead de hydration e dirty checking pode se tornar significativo. Nesse caso, escrever repositórios customizados com queries parametrizadas diretamente no banco costuma ser mais eficiente.
A escolha entre entidadessimples, agregados com domínio rico ou puro mapeamento tabela depende do volume de dados, da complexidade das regras e da equipe. Não existe resposta universal. O que funciona num projeto de startup com cinco desenvolvedores provavelmente quebra num sistema bancário com requisições simultâneas elevadas. O importante é entender o conceito antes de escolher a ferramenta. Quando alguém pergunta o que são entidades, a resposta curta é: objetos que representam dados persistentes com identidade. A resposta longa é muito mais complicada e depende do contexto em que você está trabalhando.