Relacionamentos um-para-muitos e muitos-para-muitos
Mapeie @OneToMany, @ManyToMany e @JoinTable com tipos de cascata e estratégias de busca.
Relacionamentos um-para-muitos e muitos-para-muitos é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
Tipos de relacionamento no JPA
O JPA é compatível com quatro tipos de relacionamento: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany. Cada um mapeia restrições de chave estrangeira ou de tabela de junção.
@ManyToOne: O lado proprietário
Um relacionamento muitos-para-um (por exemplo, muitos pedidos pertencem a um User) é mapeado com @ManyToOne e um @JoinColumn para a chave estrangeira.
@Entity
public class Order {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
}@OneToMany: O lado inverso
O lado inverso (User possui muitos pedidos) usa @OneToMany(mappedBy = "user"). O atributo mappedBy aponta para o campo no lado proprietário que contém a FK.
@Entity
public class User {
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Order> orders = new ArrayList<>();
}Auxiliar de consistência bidirecional
Com associações bidirecionais, mantenha os dois lados do relacionamento em um método auxiliar para manter o grafo de objetos consistente antes de sincronizar as alterações.
public void addOrder(Order order) {
orders.add(order);
order.setUser(this); // keep both sides in sync
}
public void removeOrder(Order order) {
orders.remove(order);
order.setUser(null);
}Tipos de propagação
CascadeType.ALL propaga todas as operações (persistir, mesclar, remover, atualizar e desanexar) do pai para a entidade filha. PERSIST e MERGE são opções seguras comuns. REMOVE exclui as entidades filhas quando a entidade pai é excluída.
@OneToMany(mappedBy = "user",
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
orphanRemoval = true)
private List<Order> orders;orphanRemoval: Exclusão automática de entidades filhas
orphanRemoval = true exclui uma entidade filha quando ela é removida da coleção da entidade pai — mesmo sem uma chamada explícita a entityManager.remove().
user.getOrders().remove(order); // triggers DELETE for the orphaned order on flush@ManyToMany com @JoinTable
Um relacionamento muitos-para-muitos (por exemplo, entre Student e curso) usa uma tabela de junção. Defina-a no lado proprietário com @JoinTable; o lado inverso usa mappedBy.
@Entity
public class Student {
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private Set<Course> courses = new HashSet<>();
}Colunas adicionais na tabela de junção
Quando a tabela de junção precisa de colunas adicionais (por exemplo, a data de matrícula), converta @ManyToMany em dois relacionamentos @OneToMany / @ManyToOne com uma nova entidade que represente a tabela de junção.
@Entity
public class Enrollment {
@ManyToOne Student student;
@ManyToOne Course course;
private LocalDate enrolledAt;
}FetchType: LAZY vs EAGER
Carregamento padrão: @ManyToOne e @OneToOne são EAGER (carregados imediatamente). @OneToMany e @ManyToMany são LAZY (carregados quando acessados). Sempre use LAZY para coleções a fim de evitar consultas N+1.
// Always override to LAZY:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
private Category category;Problema da consulta N+1
Acessar uma coleção lazy dentro de um loop dispara uma consulta por entidade (N+1). Corrija isso usando JOIN FETCH em JPQL ou @EntityGraph para carregar a coleção em uma única consulta.
// N+1 problem:
List<User> users = repo.findAll();
users.forEach(u -> u.getOrders().size()); // 1 + N queries!
// Fix:
@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders")
List<User> findAllWithOrders();Set vs List para coleções
Use Set para @ManyToMany (evita linhas duplicadas na tabela de junção). Use List para @OneToMany quando a ordem for importante. Nunca use List com @ManyToMany — isso faz o Hibernate excluir e reinserir todas as linhas.
Verificação rápida
O que mappedBy indica em uma anotação @OneToMany?
Recapitulação
Use @ManyToOne+@JoinColumn no lado proprietário (FK). Use @OneToMany(mappedBy=...) no lado inverso. Sempre use LAZY para coleções. Corrija N+1 com JOIN FETCH. Use uma entidade de junção para relacionamentos muitos-para-muitos com colunas adicionais.
Perguntas Frequentes
A aula “Relacionamentos um-para-muitos e muitos-para-muitos” é grátis?
Sim — o texto completo de “Relacionamentos um-para-muitos e muitos-para-muitos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Relacionamentos um-para-muitos e muitos-para-muitos”?
Mapeie @OneToMany, @ManyToMany e @JoinTable com tipos de cascata e estratégias de busca. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Relacionamentos um-para-muitos e muitos-para-muitos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Mapeamento de entidades com anotações JPA
- Repositórios do Spring Data e métodos de consulta
- Relacionamentos um-para-muitos e muitos-para-muitos
- Paginação, ordenação e projeções