Duvida Hibernate (interessante)

7 respostas
G

Olá a todos,

como se sabe, no Hibernate o mapeamento entre as classes e as tabelas no banco é feito através de uma relação entre atributos e campos.

Desta forma, o id (que é visto como uma PK no banco) é associado com um id na classe.

Mas o que me encabula é o atributo id na classse, pois ele é um atributo estranho à classe, ou seja, ele não representa nada para a classe.

Para mim, um framework de persistência é que deveria realizar uma abstração neste ponto, ou seja, não seria necessário eu ter que escrever um atributo a mais na minha classe apenas para referenciar uma PK lá no banco.

Desta forma eu pergunto: tem como eu trabalhar apenas com o hibernate omitindo este atributo? Quero fazer que isso fique “invisível” para mim, que o Hibernate faça a associação do PK com o OID do objeto mas sem precisar que na classe tenha realmente a presença do atributo id.

Valew galera…

7 Respostas

J

O atributo não é estranho à classe, ele é sim necessario para o restante da aplicação…

Um Cliente por exemplo tem um codigo, e esse codigo é necessario, não só para o banco mas sim para o restante do sistema.

Um Usuario pode ter um cpf que seria a chave, e esse atributo não é “estranho” à classe.

Até porque a persistencia deve ser totalmente desacoplada do restante da aplicação, mas o restante da aplicação tambem necessita verificar a identidade do objeto, se o framework de persistencia controlasse isso de alguma forma magica, o restante da aplicação ficaria fortemente acoplado a ele.

A ideia é essa, a identidade do objeto é baseada nos seus atributos, um ou varios deles… não há outra forma de fazer isso, nem deveria haver.

L

Além do que o Jair disse, vc não precisa ter ID nenhum, mesmo numa tabela no BD não precisa do ID, desde que vc tenha uma chave primaria e unica. Você pode implementar tudo com chaves compostas, excluindo ID totalmente da aplicação e do BD… mas a complexidade aumenta consideravelmente em ficar criando chaves compostas.

Ex. Você não pode ter dois telefones (nossa que tosco) com mesmo DDI, DDD e numero, isso reflete em uma chave unica numa tabela de Telefone, poderia ser primaria, mas eu crio um ID primario e unico para simplificar relacionamentos etc não faz sentido ter uma informação ID para uma tabela telefone também. Da mesma forma vc pode criar sua classe dizendo que o que identifica ela eh o DDI, DDD e numero, mas ai vai ter que criar a chave composta, lidar com essa chave composta, moh saquinho… na minha opinião, o ID para as coisas é uma evolução para simplificar o desenvolvimento, eu ja trabalhei num ERP que tem tabelas com 7 campos que formam a chave primaria, olha que inferno para lidar com esses dados, mesmo na aplicação se vc não tiver o ID, cada vez que vc quer buscar um telefone, tem que popular DDI, DDD e numero, vai ter que manter muito mais carregada a memoria do que se tivesse apenas um long la representando o registro como um todo.

Mas se quizer, pode tirar o ID fora, eh soh fazer tudo como chaves compostas hehe :wink:

ps: eu entendi que o que vc quiz dizer com ID eh aquele ID (numerozinho, long na maioria das vezes), que identifica um registro/objeto heheh e que saiba a nescessidade de se ter identificadores unicos para registros, classes que representam dados :razz:

G

Bom amigos, obrigado pela troca de experiência, mas minha dúvida ainda persiste (heheeh)

Vejam só, qdo eu digo que o “id” é estranho à classe é com uma visão conceitual.

Por exemplo, na abstração OO de uma aeronave, para um sistema de controle de aeronaves. Um avião tem tamanho, # de passageiros, cor, etc., mas não tem “id”, ou seja, o “id” foi inserido neste meio por conta da tecnologia. Eu poderia colocar o # chassi (sei lah se avião tem isso, hehe) como chave primária? Sim poderia, mas o problema é o seguinte: se um dia, alguém disse que dois aviões podem ter # de chassis iguais? Parece loucura, talvez seja, mas nós sabemos que isso pode um dia acontecer. CPF hoje identifica apenas uma pessoa, mas um dia ele já foi do marido e da esposa.

Desta forma, as atuais literaturas de banco de dados sugerem que a PK venha a ser um campo que não tenha nada a ver com a entidade. Mas aih eh outro assunto… outra viagem mais longa…

Mas eu quero chegar no seguinte ponto: um framework de persistêcia têm que realizar o mapeamento O/R relacionando o OID do objeto à PK ou FK do registo nas tabelas, sendo assim desnecessário a presença do “id” na classe, que não representa nada para o objeto e muito menos para o avião - como dito anteriormente. Contudo o “id” continua existente na tabela, mas a associação é feita entre o “OID” do objeto instanciado e o PK do registro no banco.

Blz!! Vamos esquentar este tópico!!!
Gosto de discussões assim!!!
Abraços e obrigado pela atenção.

J

Na realidade o “id” é estranho a classe. Mas desde o momento que você está trabalhando em mundo mundo OO persistindo em BD Relacional você não tem como fugir disso.

Porém, você pode abstrair isso, usando o atributo “id” como privado em sua classe, e fazendo qeu o hibernate só leia ele através de reflection (setando access=“field”), assim sua “aplicação” não verá este ID, porém ela existirá. Assim sendo vc não deixa sua aplicação hibrida, ou feia como alguns falam.

Contudo, este modelo de manter o seu id “visível” torna-se viával para alguns casos, diminuindo as consultas a banco de dados, fazendo com queo hibernate utilize alguns métodos de verificação de mudanças no objeto, somente antes de salvar, etc…

Tem um aspecto sitado pelo Jair, que é bem pertinente, que é o caso da sua aplicação ser identificada pela chave que realmente diz respeito a classe. Mas como vemos no mundo ER, isso não torna-se muito viável, devido a relacionamentos e tudo mais.

Creio que no seu caso, um modelo de persistência de objetos cairia melhor, já que sua idéia é muito “pura”! =)

Abraços!

J

Ahhh lembrei de uma coisa pertinente tbm.

Quando vc faz uma classe “Serializable”, há a necessidade de um atributo long “serialVersionUID”. Para que? Para que uma classe seja identificada como única, para que ela possa ser identificada.

A sua idéia de OO está correta, mas lembre-se que não estamos em um mundo puramente OO. =)

J

O Jdo não usa o id na classe, ele prega uma abstração mais OO. Como vc queria. Eu uso o JPOX, que é uma implementação free do JDO. Dá uma olhada. www.jpox.org

L

“glauber_rochab”:
Bom amigos, obrigado pela troca de experiência, mas minha dúvida ainda persiste (heheeh)

Vejam só, qdo eu digo que o “id” é estranho à classe é com uma visão conceitual.

Por exemplo, na abstração OO de uma aeronave, para um sistema de controle de aeronaves. Um avião tem tamanho, # de passageiros, cor, etc., mas não tem “id”, ou seja, o “id” foi inserido neste meio por conta da tecnologia. Eu poderia colocar o # chassi (sei lah se avião tem isso, hehe) como chave primária? Sim poderia, mas o problema é o seguinte: se um dia, alguém disse que dois aviões podem ter # de chassis iguais? Parece loucura, talvez seja, mas nós sabemos que isso pode um dia acontecer. CPF hoje identifica apenas uma pessoa, mas um dia ele já foi do marido e da esposa.

Desta forma, as atuais literaturas de banco de dados sugerem que a PK venha a ser um campo que não tenha nada a ver com a entidade. Mas aih eh outro assunto… outra viagem mais longa…

Mas eu quero chegar no seguinte ponto: um framework de persistêcia têm que realizar o mapeamento O/R relacionando o OID do objeto à PK ou FK do registo nas tabelas, sendo assim desnecessário a presença do “id” na classe, que não representa nada para o objeto e muito menos para o avião - como dito anteriormente. Contudo o “id” continua existente na tabela, mas a associação é feita entre o “OID” do objeto instanciado e o PK do registro no banco.

Blz!! Vamos esquentar este tópico!!!
Gosto de discussões assim!!!
Abraços e obrigado pela atenção.

eu até concordo que id não faz parte, mas num modelo computacional, não tem como vc fingir que ele não existe, talvez isso seja bonito/elegante em aplicações extremamente pequenas ou didáticas, mas qdo a coisa eh maior e mais seria, o bixo pega e o id eh o cara heheh vc concorda que o objeto tb precisa de algo que identifique ele?! teoricamente não existem dois aviões, blz, pode-se distinguir pelo chassi, então eu implementaria o equals verificando o chassi, mas como vc disse, vai que um dia resolvam fabricar um avião com mesmo chassi?! vc tem no seu sistema o mesmo problema que teria no banco de dados, vc vai mandar atualizar um avião com chassi ‘XXX’ que esta em uma lista de objetos sem ‘id’, que avião vc vai atualizar se esta lista conter dois aviões com o mesmo chassi que vc quer? o motivo de ter id num modelo de objetos é o mesmo motivo que ter id no modelo de banco de dados… só que se o hibernate “controlasse” isso, acho vc teria os seguintes problemas:

  1. seria obrigado a ter uma chave unica para cada tabela além da chave primaira (id), pois como o hibernate iria saber que aquele objeto é o registro com id X no banco de dados, ja que o objeto não tem o id? embora eu ache que toda tabela além da PK deveria conter uma chave unica, pode ser que a pessoa não queira criar essa chave, ou não exista uma chave unica que pode ser criada .
  2. criando essa chave, o teste de equals do seu objeto sera essa chave unica tb, uma busca por detalhes no banco de um objeto listado teria que encapsular todos campos da chave dele e não só o id, imagina que esse objeto tenha 7 campos que forma a chave unica, o objeto tera 7 atributos no equals, para vc buscar os detalhes de um objeto desse com um findPK teria que preencher esses 7 atributos, sendo que poderia apenas atribuir o id dele.
  3. se essa chave unica mudar, vc tera que alterar não apenas na persistencia na base do objeto e sim em todo lugar que faz uma consulta (findPK) dele, a inclusão de um novo campo na chave unica iria acarretar modificações pra … hehe imagina alterar todo um ERP para colocar um campinho a mais em todas as consultas que o ERP faz nessa tabela?
  4. esse ultimo eh o pior para mim, se ocorrer o problema do chassi duplicado do avião?! a tua chave unica falhou, o cliente diz que pode incluir o que quizer, ele vai fabricar aviões com o mesmo nome, mesmo chassi, virou uma zona total a empresa dele, vc vai ter que excluir a sua chave unica, ai como fica sua aplicação!? vc não tem mais na aplicação como controlar qual é avião na base que o cara esta alterando, qual o avião na base que o cara quer excluir, porque existem dois aviões com os mesmos dados, eles iguais!! ai ferro tudo, vc tem uma base certa, com id e tudo, mas a sua aplicação não ve o id, vc vai olhar para o hibernate, encapsulando e escondendo da aplicação esse id e vai querer matar quem fez isso heheh

ps: não vi o jpox que o javapablo falou, vou dar uma olhada mais tarde (se der tempo aqui hehe)… mas se ele fizer isso, queria saber como ele resolve os problemas que eu mencionei…

Criado 20 de outubro de 2006
Ultima resposta 25 de out. de 2006
Respostas 7
Participantes 5