[RESOLVIDO] Relacionamento 1:N

10 respostas
G

Bom dia.

Gostaria de tirar uma dúvida no relacionamento entre algumas classes:

Possuo uma classe Pessoa que se relaciona com a classe Endereco. Este relacionamento é 1:N (uma Pessoa poderá ter muitos endereços e um endereço pertence a apenas uma pessoa). Desta classe pessoa, herdam a classe cliente, funcionário, etc. Porém, existe uma outra classe que também terá endereço, porém não é uma pessoa, o que não caracteriza a Herança. Como poderia resolver este problema? Utilizando Interface? Alguma outra opção?

Desde já agradeço a todos.

Gláuber

10 Respostas

drsmachado

Então, mesmo sendo 1 : N, é possível criar uma tabela associativa para referenciar este relacionamento, caso a tabela fraca também se relacione com outras tabelas.
Como assim? Pessoas tem endereços, fornecedores também possuem endereços. Pessoas são diferentes de fornecedores, logo, não há herança.
Assim sendo, temos Pessoa 1 : N Endereço e Fornecedor 1 : N Endereço.
A idéia geral seria criar uma tabela endereço com uma chave estrangeira referenciando a chave primária de Pessoa e outra referenciando a chave primária de Fornecedor. Este modelo não me agrada, afinal, teríamos colunas vagas (ou pessoa_id ou fornecedor_id).
Desta forma, eu criaria as tabelas pessoa_endereco e fornecedor_endereco, onde colocaria as colunas pessoa_id e endereco_id e fornecedor_id e endereco_id.
Isso me garantiria que posso até adicionar novas tabelas que tenham o mesmo relacionamento com endereço que não teria qualquer problema.

G

Muito obrigado pelo esclarecimento. Neste caso, teria uma classe associativa entre Pessoa e Endereço, outra classe associativa entre Fornecedor e Endereço? É isso?

wbdsjunior

drsmachado:
Então, mesmo sendo 1 : N, é possível criar uma tabela associativa para referenciar este relacionamento, caso a tabela fraca também se relacione com outras tabelas.
Como assim? Pessoas tem endereços, fornecedores também possuem endereços. Pessoas são diferentes de fornecedores, logo, não há herança.
Assim sendo, temos Pessoa 1 : N Endereço e Fornecedor 1 : N Endereço.
A idéia geral seria criar uma tabela endereço com uma chave estrangeira referenciando a chave primária de Pessoa e outra referenciando a chave primária de Fornecedor. Este modelo não me agrada, afinal, teríamos colunas vagas (ou pessoa_id ou fornecedor_id).
Desta forma, eu criaria as tabelas pessoa_endereco e fornecedor_endereco, onde colocaria as colunas pessoa_id e endereco_id e fornecedor_id e endereco_id.
Isso me garantiria que posso até adicionar novas tabelas que tenham o mesmo relacionamento com endereço que não teria qualquer problema.

Neste caso, já que o Endereço está em contextos diferentes - Pessoa e Fornecedor, Recursos Humanos e Suprimentos, ou sei lá o que - por que não criar duas tabelas para endereço - pessoa_endereco e fornecedor_endereco - que referenciam a tabela pessoa e fornecedor, respectivamente? No código, em Java, você pode manter as classes em pacotes diferentes - xx.xxx.recursohumanos.Endereco e xx.xxx.suprimentos.Endereco - e assim separar os contextos. Particularmente, prefiro essa abordagem.

drsmachado

wbdsjunior:
drsmachado:
Então, mesmo sendo 1 : N, é possível criar uma tabela associativa para referenciar este relacionamento, caso a tabela fraca também se relacione com outras tabelas.
Como assim? Pessoas tem endereços, fornecedores também possuem endereços. Pessoas são diferentes de fornecedores, logo, não há herança.
Assim sendo, temos Pessoa 1 : N Endereço e Fornecedor 1 : N Endereço.
A idéia geral seria criar uma tabela endereço com uma chave estrangeira referenciando a chave primária de Pessoa e outra referenciando a chave primária de Fornecedor. Este modelo não me agrada, afinal, teríamos colunas vagas (ou pessoa_id ou fornecedor_id).
Desta forma, eu criaria as tabelas pessoa_endereco e fornecedor_endereco, onde colocaria as colunas pessoa_id e endereco_id e fornecedor_id e endereco_id.
Isso me garantiria que posso até adicionar novas tabelas que tenham o mesmo relacionamento com endereço que não teria qualquer problema.

Neste caso, já que o Endereço está em contextos diferentes - Pessoa e Fornecedor, Recursos Humanos e Suprimentos, ou sei lá o que - por que não criar duas tabelas para endereço - pessoa_endereco e fornecedor_endereco - que referenciam a tabela pessoa e fornecedor, respectivamente? No código, em Java, você pode manter as classes em pacotes diferentes - xx.xxx.recursohumanos.Endereco e xx.xxx.suprimentos.Endereco - e assim separar os contextos. Particularmente, prefiro essa abordagem.

Você usa ou já usou hibernate?
Quando você mapeia um relacionamento 1 : N no hibernate e não especifica a join column, ele cria uma tabela intermediária, como a que eu sugeri.

wbdsjunior

drsmachado:
wbdsjunior:
drsmachado:
Então, mesmo sendo 1 : N, é possível criar uma tabela associativa para referenciar este relacionamento, caso a tabela fraca também se relacione com outras tabelas.
Como assim? Pessoas tem endereços, fornecedores também possuem endereços. Pessoas são diferentes de fornecedores, logo, não há herança.
Assim sendo, temos Pessoa 1 : N Endereço e Fornecedor 1 : N Endereço.
A idéia geral seria criar uma tabela endereço com uma chave estrangeira referenciando a chave primária de Pessoa e outra referenciando a chave primária de Fornecedor. Este modelo não me agrada, afinal, teríamos colunas vagas (ou pessoa_id ou fornecedor_id).
Desta forma, eu criaria as tabelas pessoa_endereco e fornecedor_endereco, onde colocaria as colunas pessoa_id e endereco_id e fornecedor_id e endereco_id.
Isso me garantiria que posso até adicionar novas tabelas que tenham o mesmo relacionamento com endereço que não teria qualquer problema.

Neste caso, já que o Endereço está em contextos diferentes - Pessoa e Fornecedor, Recursos Humanos e Suprimentos, ou sei lá o que - por que não criar duas tabelas para endereço - pessoa_endereco e fornecedor_endereco - que referenciam a tabela pessoa e fornecedor, respectivamente? No código, em Java, você pode manter as classes em pacotes diferentes - xx.xxx.recursohumanos.Endereco e xx.xxx.suprimentos.Endereco - e assim separar os contextos. Particularmente, prefiro essa abordagem.

Você usa ou já usou hibernate?
Quando você mapeia um relacionamento 1 : N no hibernate e não especifica a join column, ele cria uma tabela intermediária, como a que eu sugeri.

Ops. Li a sua mensagem e a pretendia usar como exemplo para explicar o que eu queria dizer, mas fiz besteira. Tenho a péssima mania de clicar no “citar” das mensagens para respondê-las. Eu deveria ter explicado que estava usando a sua resposta como base para a minha. Peço desculpas por isso.

G

Estou iniciando os Estudos de hibernate esta semana. Minha intenção é usá-lo. Estudei esses assuntos a muito tempo na faculdade e por isso estou apanhando!
Então, no diagrama de classes, eu crio uma classe associativa entre pessoa e endereço? E faço as mesmas coisas no Java (crio uma classe endereço, uma classe pessoa, e uma classe endereço_pessoa)? É isso ou não?

wbdsjunior
glaubersilverio:
Estou iniciando os Estudos de hibernate esta semana. Minha intenção é usá-lo. Estudei esses assuntos a muito tempo na faculdade e por isso estou apanhando! Então, no diagrama de classes, eu crio uma classe associativa entre pessoa e endereço? E faço as mesmas coisas no Java (crio uma classe endereço, uma classe pessoa, e uma classe endereço_pessoa)? É isso ou não?
Não. Você apenas compõe - ou agrega, dependendo do ponto de vista - sua entidade (classe) Pessoa com uma entidade do tipo Endereco e anota o atributo com o tipo de associação, neste caso @OneToMany. Algo como:
@Entity
@Table(name="pessoa_endereco")
public class Endereco {
    private Pessoa pessoa;
   // atributos
   // getters and setters
}

@Entity
public class Pessoa {
    @OneToMany(mappedBy="pessoa")
    private Set<Endereco> enderecos;
   // outros atributos
   // getters and setters
}
G

Mas e como faco com as demais classes que se relacionam com endereco? Desta forma eu terei que ter um atributo fornecedor por exemplo na classe endereco, e quando for pessoa ele ficara null

wbdsjunior

Como o amigo drsmachado sugeriu eu completei (ou tentei), você terá duas classes Endereco - uma para Pessoa e outra para Fornecedor. Você pode nomear as classes como nas tabelas do banco de dados PessoaEndereco e FornecedorEndereco, com comentei, criar as classes com o mesmo nome, mas em pacotes diferentes.

G

Agora consegui entender direitinho. Muito obrigado drsmachado e wbdsjunior. A ajuda de vocês foi de grande valia!

Criado 24 de junho de 2013
Ultima resposta 25 de jun. de 2013
Respostas 10
Participantes 3