Dúvida: Persistir classe que utiliza herança

Boa noite pessoal, tudo certo?

Tenho o seguinte cenário em um projeto que estou tentando desenvolver:

No banco de dados, tenho a tabela Pessoa contendo dados gerais de uma pessoa, e as tabelas Funcionário e Cliente, que possuem dados específicos destes. Já na modelagem do negócio, tenho a classe Pessoa que é estendida pelas classes Funcionário e Cliente.

Minha dúvida é como gravar as informações no Dao da classe Funcionário e Cliente? Preciso gerar dois insert’s(uma na tabela pessoa e outra na funcionário/cliente)?

Agradeço desde já qualquer ajuda. Abraços!

A ideia de que vc precisa criar uma tabela por classe não é sempre correta.

Nos casos de polimorfismo vc tem algumas opções.

PessoaFisica extends Pessoa
PessoaJuridica extends Pessoa

Pessoa juridica tem cnpj, pessoa fisica tem cpf. Ambos tem nome, telefone, id.

O que se pode fazer é uma tabela Pessoa com todos esses campos + campo tipo.

Quando o seu DAO grava ou lê ele vai saber usar os campos certos de acordo com o Tipo.

Outra forma é colocar os campos especificos em tabelas auxiliares. Assim vc insere nome em Pessoa, e tem uma PessoaFisica (ou outro nome) que tem pessoa_id + cpf.

Nesse caso vc tem que fazer 2 inserts. Mas o DAO cuida disso.

Com umas anotações o Hibernate te da isso de gratis (acho)

edit: da uma olhada nessa documentação: https://docs.jboss.org/hibernate/core/3.5/reference/pt-BR/html/inheritance.html

Complementando…e usando Hibernate… da uma olhada no link abaixo… estou com um cenário muito parecido com o seu…e optei por tabelas diferentes…na minha opinião fica mais claro…

http://www.devmedia.com.br/tipos-de-heranca-no-hibernate/28641

1 curtida

Acho que no meu caso, onde uma pessoa pode ser funcionária e cliente ao mesmo tempo, o melhor seria em tabelas diferentes, visto que o campo tipo no “tabelão” não resolveria meu problema, certo?

Abraços

qual o sentido da pessoa ser funcionario E cliente?

mesmo que tenham os mesmos atributos ( nome, cpf, etc ) geralmente vc quer fazer coisas bem distintas e independentes.

é tipo um funcionario da TIM ter um celular da TIM, vc não vai pagar parte do salario do cara em credito no celular dele, ou caso ele fique devendo vc não vai debitar do salario dele. pelo contrario são coisas bem isoladas.

imagina o call center ligando “seu fulano, o senhor tem um debito aqui de 1000 reais, estamos falando com o seu chefe nesse momento”. sem falar que se vc tem dependentes como funcionario, esse pode ser o tipo de coisa que um Cliente não queria expor pra empresa (po vcs ligaram pra minha esposa pra fazer propaganda de novo?)

pense muito bem se quer estes cenarios. é o caso onde talvez vc queira uma tabela funcionario e uma tabela cliente e pro acaso vc pode ter tabela telefone pra atender os dois, mas vc talvez não queira misturar e ter um FuncionarioCliente ( pq vc vai precisar desse tipo de classe pra representar a intersecção)

reflita. é claro que pode continuar fazendo sentido no seu caso especial

1 curtida

A questão é, pode existir um funcionário de uma loja que compre nela também(vire cliente), e não quero ter dois cadastros de uma mesma pessoa no sistema. Acho que o JOINED, conforme citado no link: http://www.devmedia.com.br/tipos-de-heranca-no-hibernate/28641 é a melhor maneira de resolver meu problema.

tudo bem.

a questão é: o quão raro isso vai ser?

pq se vc tem uma modelagem explicita com duas classes diferentes que extendem Pessoa ( assumindo Pessoa ser, por exemplo, abstract ), vc vai precisar de uma terceira classe que seja a união dos dois campos.

E perceba que um FuncionarioCliente nesse caso É UM Cliente e É UM Funcionario. Como ja não permite herança multipla a unica possibilidade é que Funcionario e Cliente sejam interfaces para uma das 3 classes.

abstract class Pessoa {}
interface Cliente {}
interface Funcionario {}
class ClienteImpl implements Cliente extends Pessoa {}
class FuncionarioImpl implements Funcionario extends Pessoa {}
class ClienteFuncionarioImpl implements Cliente, Funcionario extends Pessoa {}

Pessoa p = new ClienteFuncionarioImpl(); // ok
Cliente c = new ClienteFuncionarioImpl(); // ok
Funcionario f = new ClienteFuncionarioImpl(); //ok

Cliente c = new ClienteImpl(); // ok
Funcionario f = new ClienteImpl(); // NAO PODE

olha a confusão que é esse modelo de dados se vc quiser tipagem forte.

vc vai ter que fazer algo como

pessoa.isCliente()
pessoa.isFuncionario()

Se isso acontece em 1% ou menos dos casos acredite, vc pode assumir dois cadastros diferentes que o seu modelo de dados, classes, etc, ficarão muito mais simples.

De novo, eu não sou o dono da verdade, mas existem implicações importantes nessa modelagem. A minha experiencia diz para evitar.

1 curtida

São entidades diferentes, cada um com sua história e interesses gerenciais próprios. A gerência do setor de vendas geralmente quer focar na pessoa como a importância de ser cliente, independente da vida dele na empresa como funcionário.

Uma funcionária pode ser demitida com o nome de casada e assim foi de fato. Quando passar a ser cliente ela vai poder se cadastrar como cliente do jeito que ela quiser, com outro telefone, com outro endereço, nome de solteira, e não ficar atualizando informações do setor de RH. Isto é só um exemplo que me vem a cabeça, de experiência real que passei é assim que estava modelado a parte de vendas. Eu não era dono da modelagem, só estou falando experiência que passei. Então cuidado com esses exemplos acadêmicos, crie uma tabela para cada uma dessas entidades.

Só para deixar claro, estou falando a nível de modelagem de dados/tabelas físicas, não trabalho com modelagem orientada objetos pra poder te ajudar no restante da questão.

javaflex, Você optaria na modelagem do banco de dados ter as 3 tabelas(Pessoa, Cliente e Funcionário), tendo nas tabelas clientes e funcionário uma chave estrangeira com o código da Pessoa?

Não leve como verdade absoluta, mas conforme comentei acima sobre a experiência que passei, seria duas tabelas: Cliente e Funcionario. E se tiver pessoa juridica, tambem vai ser outra tabela, Empresa.