Ola PessoAll!Primeiramente, gostaria de agradecer a todos que tem seguido e contribuido com a divulgacao deste meu humilde blog e, pelos positivos feedbacks que tenho recebido. Fico feliz nao apenas por apreciarem o conteudo que disponibilizo, mas por contribuirem com a divulgacao do amplo ecossistema Java, que sustenta desde grandes organizacoes ate muitos de nos rs!Neste post vou dar continuidade ao uso de relacionamentos com JPA, neste, verificaremos como implementar uma relacao do tipo N:N (muitos para muitos - @ManyToMany). Para demonstrar este relacionamento, darei continuidade no projeto ja iniciado nos posts de JPA anteriormente, ate entao temos a relacao 1:N entre Produto e Categoria.Contexto: do que ja foi implementado ate o momento, consegue-se categorizar os produtos, logo, facilmente obtemos todos os produtos de uma dada categoria. Imagine que queremos catalogar todos os produtos que um usuario (cliente) visite, para que futuramente, possa-se tracar um perfil de consumo. O que envolve nisto: logo, um usuario podera ver mais de um produto, e um produto sera visualizado por mais de um usuario, o que caracteriza a relacao N:N.ModelagemComo dito, teremos um relacionamento N:N entre cliente e produto, para contemplar este requisito, nossa modelagem ficara da seguinte forma:Para efetuarmos as alteracoes, temos o seguinte sql:create table cliente (id_cliente serial,nome varchar(70),primary key (id_cliente));create table cliente_produto_rel (id_cliente integer,id_produto integer,primary key (id_cliente, id_produto),foreign key (id_cliente) references cliente (id_cliente),foreign key (id_produto) references produto (id_produto));IMPLEMENTACAOO primeiro passo, e procedermos a modelagem ORM da nova entidade (cliente) e realizar o mapeamento bi-direcional entre cliente e produto. Assim, temos:Cliente:package br.com.serjava.persistencia.entity;//imports omitidos/** * The persistent class for the cliente database table. * */@Entitypublic class Cliente implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name="CLIENTE_IDCLIENTE_GENERATOR", sequenceName="CLIENTE_ID_CLIENTE_SEQ", allocationSize=1) @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CLIENTE_IDCLIENTE_GENERATOR") @Column(name="id_cliente") private Integer idCliente; private String nome; //bi-directional many-to-many association to Produto @ManyToMany @JoinTable( name="cliente_produto_rel" , joinColumns={ @JoinColumn(name="id_cliente") } , inverseJoinColumns={ @JoinColumn(name="id_produto") } ) private List listaProdutos; //getters and settersProduto:package br.com.serjava.persistencia.entity;//imports omitidos/** * The persistent class for the produto database table. * */@Entitypublic class Produto implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name="PRODUTO_IDPRODUTO_GENERATOR", sequenceName="PRODUTO_ID_PRODUTO_SEQ") @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PRODUTO_IDPRODUTO_GENERATOR") @Column(name="id_produto") private Integer idProduto; @Column(name="nm_produto") private String nomeProduto; private Integer quantidade; private Double valor; //bi-directional many-to-many association to Cliente @ManyToMany(mappedBy="listaProdutos") private List listaClientes; //bi-directional many-to-one association to Categoria @ManyToOne @JoinColumn(name="id_categoria") private Categoria categoria;Observe que ambas entidades, Cliente e Produto, possuem uma List referenciando-se uma a outra, o que caracteriza o relacionamento N:N. No mapeamento da entidade Cliente, observe que o join que interliga as 2 entidades por meio da entidade rel, e realizado por meio da anotacao propria: @JoinTable.Devemos criar a camada de persistencia da nova entidade, Cliente. Faca de forma analoga as demais entidades (em caso de duvidas consulte os posts anteriores sobre JPA).Considerando que ja temos produtos persistidos no database, vamos recupera-los e associalos a um novo cliente que supostamente esta visitando aqueles produtos em uma pagina; como o metodo save implementado no dao generico (DAOImpl) retorna o objeto persistido (cliente), conseguiremos tambem obter os produtos associados ao cliente, por meio da relacao, como mostra a implementacao:ProdutoDAO produtoDAO = new ProdutoDAOImpl(); ClienteDAO clienteDAO = new ClienteDAOImpl(); //obtem-se a lista