0Pricing
Java Academy · Aula

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

  1. Mapeamento de entidades com anotações JPA
  2. Repositórios do Spring Data e métodos de consulta
  3. Relacionamentos um-para-muitos e muitos-para-muitos
  4. Paginação, ordenação e projeções
← Voltar para Java Academy