ManyToMany x ManyToOne: Quando usar?

13 respostas
J

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!

13 Respostas

H

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.

J

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.

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

H

jeanmalvessi:
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.

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

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

J

Hebert Coelho:
jeanmalvessi:
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.

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

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

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

Y

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

H

jeanmalvessi:
O conceito pode estar errado, mas funciona. Já vi sistemas operando com o modelo ManyToOne para este caso. Isto que me confundiu.
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.

J

Hebert Coelho:
jeanmalvessi:
O conceito pode estar errado, mas funciona. Já vi sistemas operando com o modelo ManyToOne para este caso. Isto que me confundiu.
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.

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

H

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 ?
Eu digo que errado está sua análise ao falar que ambos os casos servem para você.

J

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.

H

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.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.

J

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.

Foi o que eu falei aqui:

H

jeanmalvessi:
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.

Foi o que eu falei aqui:

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 ?
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.

S

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

Criado 19 de março de 2013
Ultima resposta 19 de mar. de 2013
Respostas 13
Participantes 4