ManyToMany x ManyToOne: Quando usar?

Bom dia pessoal!

Gostaria de tirar uma dúvida que venho tendo a tempos… qual a vantagem de se usar relacionamento ManyToMany ao invés de ManyToOne ?

Vou dar um exemplo prático:

Suponhamos a relação Pessoa x Endereço.

ManyToOne

/**
 *
 * @author jean
 */
@Entity
public class Pessoa implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "nome")
    private String nome;
    
    @Column(name = "cpf")
    private String cpf;
    
    @Column(name = "idade")
    private Integer idade;
    
    @Column(name = "sexo")
    private String sexo;

    //Get e set, hascode e equals, toString
}

/**
 *
 * @author jean
 */
@Entity
public class Endereco implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "logradouro")
    private String logradouro;
    
    @Column(name = "numero")
    private String numero;
    
    @Column(name = "bairro")
    private String bairro;
    
    @ManyToOne
    @JoinColumn(name = "pessoa")
    private Pessoa pessoa;

    //Get e set, hascode e equals, toString
}

Na hora de inserir no banco:

for (Endereco endereco : listaEnderecos) {
     endereco.setPessoa(pessoa);
     enderecoJpa.create(endereco);
}

Para recuperar:
Os endereços terão o código da pessoa e na hora de fazer a busca, basta fazer um find na tabela endereco where pessoa = pessoaDesejada.
Se quiser saber as pessoas de um determinado endereco basta selecionar endereco.pessoa where endereco = (parametros).

ManyToMany

/**
 *
 * @author jean
 */
@Entity
public class Pessoa implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo_pessoa;
    
    @Column(name = "nome")
    private String nome;
    
    @Column(name = "cpf")
    private String cpf;
    
    @Column(name = "idade")
    private Integer idade;
    
    @Column(name = "sexo")
    private String sexo;
    
    @ManyToMany
    @JoinTable(name = "pessoaendereco", joinColumns = {
        @JoinColumn(name = "codigo_pessoa")},
    inverseJoinColumns = {
        @JoinColumn(name = "codigo_endereco")})
    @Cascade({org.hibernate.annotations.CascadeType.ALL})
    private Collection<Endereco> enderecos;

    //Get e set, hascode e equals, toString
}

/**
 *
 * @author jean
 */
@Entity
public class Endereco implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo_endereco;

    @Column(name = "logradouro")
    private String logradouro;
    
    @Column(name = "numero")
    private String numero;
    
    @Column(name = "bairro")
    private String bairro;
    
    @ManyToMany
    @JoinTable(name = "pessoaendereco", joinColumns = {
        @JoinColumn(name = "codigo_endereco")},
            inverseJoinColumns = {
        @JoinColumn(name = "codigo_pessoa")})
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    private Collection<Pessoa> pessoas;

    //Get e set, hascode e equals, toString
}

/**
 *
 * @author jean
 */
@Entity
public class PessoaEndereco implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @ManyToOne
    @JoinColumn(name = "codigo_pessoa")
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    private Pessoa codigo_pessoa;
    
    @Id
    @ManyToOne
    @JoinColumn(name = "codigo_endereco")
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    private Endereco codigo_endereco;

    //Get e set
}

Na hora de inserir no banco:

pessoa.setEnderecos(listaEnderecos);
pessoaJpa.crete(pessoa);

Para recuperar:

pessoa.getEnderecos();
endereco.getPessoas();

Enfim
Vejo os 2 casos resolvendo meu problema e o ManyToMany me parece mais complicado por criar uma tabela a mais… pensando em um sistema grande, a quantidade de tabelas aumentaria consideravalmente. Porém é muito mais fácil de inserir e buscar os endereços da pessoa e vice versa. Quando se usa um e quando se usa o outro ? O que se ganha com um e o que se perde com o outro ?

E o mais importante: é uma má prática de programação aplicar o relacionamento ManyToOne em um caso como este ?

Obrigado!

Veja se te ajuda: JPA: Mini Livro - Primeiros passos e conceitos detalhados

Conceitualmente não existe modelagem onde ManyToOne e ManyToMany poderiam ser utilizados. Ou é um, ou é o outro.

[quote=Hebert Coelho]Veja se te ajuda: JPA: Mini Livro - Primeiros passos e conceitos detalhados

Conceitualmente não existe modelagem onde ManyToOne e ManyToMany poderiam ser utilizados. Ou é um, ou é o outro.[/quote]

Sei que ou é um ou é outro… por isso mesmo estou perguntando quando se usa e se o ManyToOne é uma má prática, visto que os 2 resolveram o meu problema.

Obrigado

[quote=jeanmalvessi][quote=Hebert Coelho]Veja se te ajuda: JPA: Mini Livro - Primeiros passos e conceitos detalhados

Conceitualmente não existe modelagem onde ManyToOne e ManyToMany poderiam ser utilizados. Ou é um, ou é o outro.[/quote]

Sei que ou é um ou é outro… por isso mesmo estou perguntando quando se usa e se o ManyToOne é uma má prática, visto que os 2 resolveram o meu problema.

Obrigado[/quote]Não tem como. Ou você precisa de uma lista nas duas pontas, ou de apenas um objeto. Seu conceito que está errado.

[quote=Hebert Coelho][quote=jeanmalvessi][quote=Hebert Coelho]Veja se te ajuda: JPA: Mini Livro - Primeiros passos e conceitos detalhados

Conceitualmente não existe modelagem onde ManyToOne e ManyToMany poderiam ser utilizados. Ou é um, ou é o outro.[/quote]

Sei que ou é um ou é outro… por isso mesmo estou perguntando quando se usa e se o ManyToOne é uma má prática, visto que os 2 resolveram o meu problema.

Obrigado[/quote]Não tem como. Ou você precisa de uma lista nas duas pontas, ou de apenas um objeto. Seu conceito que está errado.[/quote]

O conceito pode estar errado, mas funciona. Já vi sistemas operando com o modelo ManyToOne para este caso. Isto que me confundiu.

Hebert, me corrija se eu estiver errado xD

mas acho que voce tem que pensar assim:
se um endereço puder ser de varias pessoas, e varias pessoas tiverem um endereço, voce coloca o relacionamento many to many,

se um endereço puder ser de varias pessoas,mas cada pessoa so tiver um endereço, o endereço fica na pessoa e o relacionamenteo é one to many

[quote=jeanmalvessi]O conceito pode estar errado, mas funciona. Já vi sistemas operando com o modelo ManyToOne para este caso. Isto que me confundiu.[/quote]Nem todo código vai estar conceitualmente correto.

Nem todo relacionamento precisa ser bidirecional, ainda assim funciona.

Nem tudo que não funciona está conceitualmente errado.

Uma coisa é conceito e outra é utilização da ferramenta.

[quote=Hebert Coelho][quote=jeanmalvessi]O conceito pode estar errado, mas funciona. Já vi sistemas operando com o modelo ManyToOne para este caso. Isto que me confundiu.[/quote]Nem todo código vai estar conceitualmente correto.

Nem todo relacionamento precisa ser bidirecional, ainda assim funciona.

Nem tudo que não funciona está conceitualmente errado.

Uma coisa é conceito e outra é utilização da ferramenta.[/quote]

Quer dizer então que neste caso, conceitualmente falando, o correto é utilizar o ManyToMany ? E que o ManyToOne é uma má utilização da ferramenta ?

[quote=jeanmalvessi]Quer dizer então que neste caso, conceitualmente falando, o correto é utilizar o ManyToMany ? E que o ManyToOne é uma má utilização da ferramenta ?[/quote]Eu digo que errado está sua análise ao falar que ambos os casos servem para você.

Como posso estar errado se mostrei um exemplo e falei que já vi sistemas operando desta forma ? Acho que você que não está me entendendo.

Como posso estar errado se mostrei um exemplo e falei que já vi sistemas operando desta forma ? Acho que você que não está me entendendo.[/quote]E aí que eu volto a falar. Você pode estar com um código certo mas conceitualmente errado.

Você pode usar uma colher para cavar um buraco. É o correto? Não. Mas funciona? Sim.

[quote=Hebert Coelho]E aí que eu volto a falar. Você pode estar com um código certo mas conceitualmente errado.
Você pode usar uma colher para cavar um buraco. É o correto? Não. Mas funciona? Sim.[/quote]
Foi o que eu falei aqui:

[quote=jeanmalvessi][quote=Hebert Coelho]E aí que eu volto a falar. Você pode estar com um código certo mas conceitualmente errado.
Você pode usar uma colher para cavar um buraco. É o correto? Não. Mas funciona? Sim.[/quote]
Foi o que eu falei aqui:

[quote=jeanmalvessi]
Quer dizer então que neste caso, conceitualmente falando, o correto é utilizar o ManyToMany ? E que o ManyToOne é uma má utilização da ferramenta ?
[/quote][/quote]Cara, ManyToOne é o correto? Seu relacionamento precisa de um objeto ou uma lista? É você quem tem que utilizar a ferramenta de acordo com sua necessidade.

Pode funcionar, mas é o certo?
O conceito é: duas pessoas podem ter o mesmo endereço? Se sim, o endereço é tão importante para ser colocado em uma tabela separada?
Alguma outra entidade vai se comunicar com essa tabela de endereços de maneira objetiva?
às vezes tu cria uma complexidade desnecessária, é necessário ver sua necessidade