ManyToMany
Explicação
A anotação @ManyToMany do JPA (Java Persistence API) é usada para representar um relacionamento entre duas entidades no qual cada instância de uma entidade pode estar associada a várias instâncias da outra entidade, e vice-versa. Esse tipo de relacionamento é bidirecional, ou seja, ambas as entidades podem ter acesso umas às outras.
@ManyToMany
Exemplo
Vamos imaginar que agora a empresa solicitou uma nova funcionalidade onde os seus clientes possam selecionar produtos para torná-los como favoritos ou como conhecemos em algumas plataformas como a lista do desejos.
Por se tratar de uma relacionamento onde muitos clientes poderão adicionar muitos produtos, logo muitos produtos estarão na lista de desejos de muitos clientes, este relacionamento é conhecido como muitos-para-muitos.
import jakarta.persistence.*;
@Entity
public class Produto {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String nome;
    // Lombok ou Getters e Setters
}
Contextualização
- Anotação 
@ManyToMany: 
- Essa anotação é usada tanto na classe 
Clientequanto na classeProduto(Opcionalmente). - No lado da entidade 
Cliente, a anotação é usada para indicar que um cliente pode ter muitos produtos favoritos. - Na classe 
Produto, o relacionamento é bidirecional, então a anotação@ManyToManyé usada com o atributomappedBy, que aponta para a coleçãoprodutosFavoritosna classeCliente. Isso estabelece que a tabela intermediária será gerenciada pela classeCliente. 
- Tabela Intermediária:
 
- A tabela intermediária que vai armazenar as associações entre clientes e produtos é especificada com a anotação 
@JoinTableno lado da classeCliente. - Essa tabela será chamada 
cliente_produtoe terá duas colunas:cliente_id(chave estrangeira para a tabelaCliente)produto_id(chave estrangeira para a tabelaProduto)
 
@JoinColumneinverseJoinColumns:
@JoinColumn(name = "cliente_id")especifica a coluna na tabela intermediária que faz referência aoCliente.@JoinColumn(name = "produto_id")faz referência à coluna da tabela intermediária que se relaciona comProduto.
- Bidirecionalidade:
 
- O lado da classe 
Produtousa o atributomappedBy = "produtosFavoritos". Isso indica que a tabela intermediária é controlada pela classeCliente, ou seja, a associação é gerenciada a partir do lado da classeCliente, enquanto o lado da classeProdutoapenas referencia esse relacionamento. 
Como funciona a relação
- Quando um cliente favoritar um produto, o relacionamento é adicionado à tabela intermediária 
cliente_produto, armazenando ocliente_ide oproduto_id. - Da mesma forma, ao favoritar vários produtos, o cliente estará associado a esses produtos através da tabela intermediária, e o produto, por sua vez, será associado ao cliente na tabela de associação.
 
Conclusão
O relacionamento @ManyToMany é muito útil para representar situações onde entidades possuem relações mútuas entre si, como o exemplo de clientes e produtos favoritos. A anotação permite que você gerencie essas associações de maneira simples, com a ajuda de uma tabela intermediária que facilita o gerenciamento das chaves estrangeiras.