Hibernate - Herança entre entidades

1 resposta
K

Salve amigos,

estou com uma dúvida que não pára de martelar minha cabeça. Eu já pesquisei sobre herança e sei como construi-las, mas não consigo entender o funcionamento da herança: Tabela por Sub-Classe.

Em meus estudos fiz a seguinte modelagem:
Pessoa - dados comuns a uma pessoa do sistema

Medico - dados especificos de um médico
Atendente - dados especificos de um atendente
Usuario - nome de usuario, senha e etc…

Essas três entidades herdam de Pessoa, certo? Ou seja, tenho 4 tabelas no banco, 1 de Pessoa, 1 de Medico, 1 de Atendente e 1 de Usuario.

Como vocês podem notar, não se trata de uma especialidade, onde uma pessoa pode ser 1 dos três casos. Uma pessoa pode ser Médico e pode ser também Usuário.

Fiz o mapeamento todo bonitinho através de annotations:

@Entity
@Table(name="pessoas")
@Inheritance(strategy=InheritanceType.JOINED)
public class Pessoa {
  ...
}
@Entity
@Table(name="atendentes")
@PrimaryKeyJoinColumn(name="id")
public class Atendente extends Pessoa {
  ...
}

E por aí vai…

Agora vem o que eu não entendo:

Se eu pedir um Atendente lá do banco ele faz um join certinho de atendentes x pessoas e traz tudo perfeito do jeito que eu quero.

No entanto, se eu pedir uma Pessoa do banco(não me interessa se ela é atendente, médico, usuário ou seja lá o que for) ele faz um join com todas as tabelas das classes filhas e me entrega uma instancia de uma subclasse. Por exemplo, se eu pedir a pessoa de id = 1, ele vai no banco e faz um join de pessoas x atendentes x medicos x busuarios e me entrega por exemplo uma instacia de Atendente. Tudo bem que Atendente possui todos os atributos de Pessoa e vai me servir, mas para que fazer esse join em todas as “tabelas de especialidades” se eu só quero a tabela base?

Eu não consigo entender pq o hibernate dá essa volta toda quando ele poderia simplesmente ir direto na tabela que eu pedi ignorando as subclasses, afinal, foi isso que eu pedi para ele quando dei um get(Pessoa.class, 1L), não foi?

PS.: Eu sei que posso fazer com composição usando one2one, mas eu sei também que herança é totalmente cabível nesse meu caso, então gostaria de entender o motivo do hibernate fazer o que faz, devo estar fazendo algo errado :frowning:

1 Resposta

Paulo_Silveira

Infelizmente é assim mesmo. Toda query desse jeito é polimorfica, e ele sempre vai trazer todos os dados. Entao a primeira coisa que ele faz é descobrir o tipo do objeto, e pra isso precisa consultar TODAS as tabelas filhas para saber de que tipo é aquela Pessoa.

Parece que eles vao mudar isso, pra nem toda query ser polimorfica, em especial para a JPA 2.0.

Solucoes: usar SINGLE_TABLE (sim, perdemos a normalizacao), ou trocar herança por composicao (Medico tem referencia a uma Pessoa, Pessoa tem uma referencia a PessoaTipo que é uma enumeracao).

Aqui ja discuti uma vez sobre isso:

abraços

Criado 7 de junho de 2007
Ultima resposta 7 de jun. de 2007
Respostas 1
Participantes 2