Herança ou relacionamento?

6 respostas
gustavodelgado

Tenho uma classe “Pessoa” e uma “Funcionario”.
Naturalmente, todo funcionário é uma pessoa, com alguns dados específicos.

A classe Pessoa não é abstrata… pois em alguns lugares do sistema tenho que cadastrar pessoas que não são funcionárias. Nas tabelas do banco, tenho um campo na tabela de funcionários (FK) apontando para pessoas.

Neste caso, seria melhor usar herança, ou declaro um atributo do tipo Pessoa na classe Funcionario?

Primeiro gostaria de tirar esta dúvida, pois estou fazendo agora as classes e mapeando para o hibernate.
Declarando Pessoa como um atributo de Funcionário, consegui fazer o mapeamento, porém estou tendo algumas dificuldades quando transformo isto em herança…

6 Respostas

Richeli

Talvez se vc fizesse a classe pessoa como abstrata e criasse duas instâncias dela, Uma Funcionário e outra classe “normal” vc conseguiria se achar melhor deixando as classes com relacionamento “is a”

gustavodelgado

Richeli:
Talvez se vc fizesse a classe pessoa como abstrata e criasse duas instâncias dela, Uma Funcionário e outra classe “normal” vc conseguiria se achar melhor deixando as classes com relacionamento “is a”

Para fazer isso, eu colocaria todos os atributos comuns a todas as pessoas na própria classe abstrata?? E depois crio uma classe funcionário (com seus atributos) e outra classe pessoa “normal” herdando dela, mas sem nenhum atributo?? Qual a vantagem disso?
Obrigado.

G

Caro Gustavo,
Com certaza eu faria uma generalização, isto é, faria com que Funcionario fosse uma especialização da classe pessoa.
A Classe funcionário herdará(extends) todos atributos e métodos da classe pessoa.
Mas atenção para os modificadores dos atributos e métodos.
se você usar private nos atributos da classe Pessoa, você não vai ter acesso na classe funcionario. Aconselho a usar protected nos atributos e public nos métodos. Protected dá acesso na propria classe(Pessoa), nas sub-classe (Funcionario) e nas classes no mesmo pacote onde está a classe(Pessoa).

Quanto ao banco. um campo na tabela funcionario será chave estrangeira de uma chave primaira da tabela pessoa (cdPessoa por exemplo).

Voce escolhe se essa chave estrangeira será a chave primaria da tabela funcionario tbm, ou se vc criará outro campo para chave primaria da tabela funcionario, tipo (cdFuncionario).

Espero ter ajudado.

Um abraço

Giovani

G

Lembrando que a Classe Pessoa não precisa ser Abstract para ser estendida.
Uma classe abstract significa que ela não está pronta, não podendo ser instanciada, somente estendida.

bzanchet

Inheritance Mapping

gustavodelgado

Pessoal, muito obrigado pelas dicas. Agora vou complicar um pouquinho, heheh.

Pelo que percebi, seria adequado utilizar herança mesmo neste caso. Estou tendo algumas dificuldades para fazer o mapeamento com hibernate annotations.

Olhando a documentação em
http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/
acredito que o tipo “Joined subclasses” seria mais adequado, porém minha tabela funcionários possui um ID “codigoFuncionario” que é auto-increment e um campo “codigoPessoa” que é a foreing key para a tabela pessoas.

Usando este tipo de mapeamento, pelo que vi, ele não aceita a declaração do ID auto-increment na classe Funcionario.

Seguem as classes (apenas com os campos relevantes):

@Entity
@Table(name="int_pessoas")
@Inheritance(strategy=InheritanceType.JOINED)

public class Pessoa {
    
    private Integer codigoPessoa;
    private String nomePessoa;

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Integer getCodigoPessoa() {
        return codigoPessoa;
    }

    public void setCodigoPessoa(Integer codigoPessoa) {
        this.codigoPessoa = codigoPessoa;
    }

    public String getNomePessoa() {
        return nomePessoa;
    }

    public void setNomePessoa(String nomePessoa) {
        this.nomePessoa = nomePessoa;
    }

    
}
@Entity
@Table(name="int_funcionarios")
@PrimaryKeyJoinColumn(name="codigoPessoa")

public class Funcionario extends Pessoa{
    
    private Integer codigoFuncionario;
    private String matricula;
   

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Integer getCodigoFuncionario() {
        return codigoFuncionario;
    }

    public void setCodigoFuncionario(Integer codigoFuncionario) {
        this.codigoFuncionario = codigoFuncionario;
    }


    public String getMatricula() {
        return matricula;
    }

    public void setMatricula(String matricula) {
        this.matricula = matricula;
    }

  
}

Pelo que entendi, este mapeamento é para quando você utiliza o mesmo campo “primary key” da tabela filha como sendo também a “foreing key” para a tabela pai… mas como faço para mapear quando minha foreing key é um campo diferente da primary key???

[]s

Criado 28 de novembro de 2006
Ultima resposta 29 de nov. de 2006
Respostas 6
Participantes 4