Chave primária única x Chave primária composta

1,234 views
Skip to first unread message

Nilo Lima

unread,
Jun 16, 2009, 7:09:46 PM6/16/09
to pb...@googlegroups.com, dotnetar...@googlegroups.com
Ola,

Estou com um problema para convencer uma equipe de desenvolvimento que estou entrando agora, a nao usar chaves compostas.
Dei um boa pesquisada no grupo e no google procurando uma boa bibliografia para convence-los.
Nao encontrei nada ainda. Pesquisando aqui no grupo vi que o Mauricio Linhares falou sobre o livro Domain-Driven Design de Eric Evans. Eu tenho o PDF dele aqui e busquei por primary key e composed key e nao encontrei nada.
Algu'em conhece uma boa bibliografia para eu apresentar para a equipe.
Eles tamb'em querem colocar logica de negocio no banco usando procedures,function, trigres. Tamb'em queria mostra-los que isso nao 'e bom, ja argumentei varios fatores mas acho que eles precisam ouvir ou ler um terceiro confiavel.

Gostaria da ajuda dos senhores.
Obrigado

PS: Os acentos do meu teclado estao ruins

Rayrone Zirtany

unread,
Jun 16, 2009, 7:49:54 PM6/16/09
to pb...@googlegroups.com
  Cara, isso é um pouco relativo.... há casos em que o uso de chave compostas sejam recomendadas pela formas normais, entretanto em termos de desempenho pode ser melhor. E a respeito de colocar a regra de negócio no banco através de procedures pode ser interessante se vcs tiverem certeza que não irão mudar de banco de dados, o que normalmente acontece. O que é mais comum é mudar a plataforma de desenvolvimento por exemplo: VB para JAVA.
   Mas como eu disse, isso tudo depende do caso, cabe a equipe analisar o que é mais viável...

2009/6/16 Nilo Lima <nilo.a...@gmail.com>

Rosivaldo Ramalho

unread,
Jun 16, 2009, 8:15:23 PM6/16/09
to pb...@googlegroups.com
Dependendo da tua regra de negócio você terá que criar chaves
compostas, cabe a você a aos outros desenvolvedores ver se isso é o
que vocês necessitam.

Qualquer SGBD suporta isso tranquilamente, e é óbvio que existe um
pequeno overhead no servidor em manter uma chave composta em relação a
uma chave com uma única coluna, mas isso não é algo para se preocupar.

Como o amigo Raynore falou, é mais comum fazer mudanças na plataforma
de desenvolvimento do que no banco, claro que, vamos fazer uma
ressalva, se o teu sistem está sendo pensado em rodar em diversos
bancos então é melhor esquecer isso mesmo. Se não for, então aconselho
você a deixar isso no banco, pois qualquer que seja o banco, ele será
muito mais otimizado internamente para tratar procedures/triggers, e
em muitas vezes mais rápido do que em Java.

2009/6/16 Rayrone Zirtany <rayrone...@gmail.com>:
--
Rosivaldo Azevedo Ramalho
Consultor Oracle Database / Application Server
mail/msn: rosi...@gmail.com
mobile: +55 83 8893 8281
Oracle Database 10g Certified Associate
Oracle Database 10g Certified Professional
Oracle Application Server 10g Certified Associate

Maurício Linhares

unread,
Jun 16, 2009, 9:32:23 PM6/16/09
to pb...@googlegroups.com
Opa Nilo,

2009/6/16 Nilo Lima <nilo.a...@gmail.com>:


> Ola,
>
> Estou com um problema para convencer uma equipe de desenvolvimento que estou
> entrando agora, a nao usar chaves compostas.
> Dei um boa pesquisada no grupo e no google procurando uma boa bibliografia
> para convence-los.
> Nao encontrei nada ainda. Pesquisando aqui no grupo vi que o Mauricio
> Linhares falou sobre o livro Domain-Driven Design de Eric Evans. Eu tenho o
> PDF dele aqui e busquei por primary key e composed key e nao encontrei nada.
> Algu'em conhece uma boa bibliografia para eu apresentar para a equipe.

Qualquer livro decente sobre design de bancos de dados vai falar sobre
as Surrogate Keys ( http://en.wikipedia.org/wiki/Surrogate_key ), que
são as chaves primárias sintéticas não derivadas de campos/colunas da
tabela. No artigo da Wikipedia você vai encontrar alguns dos problemas
que elas resolvem e no fim referências pra livros onde você pode se
aprofundar no assunto se for necessário.

A criação de chaves compostas através de campos derivados dos dados da
aplicação são uma prática desaconselhável a mais de três décadas.

> Eles tamb'em querem colocar logica de negocio no banco usando
> procedures,function, trigres. Tamb'em queria mostra-los que isso nao 'e bom,
> ja argumentei varios fatores mas acho que eles precisam ouvir ou ler um
> terceiro confiavel.

A lógica sobre não colocar a lógica da sua aplicação, escrita em uma
línguagem de programação orientada a objetos é bem simples, linguagens
de programação de uso genérico orientadas a objeto são muito mais
flexíveis, fáceis de manter e alterar do que linguagens como PL/SQL,
que é uma linguagem desenvolvida com um único uso em mente. Pior,
usando uma linguagem como Java você tem todo um suporte de IDEs e
ferramentas complementares, como controle de versão, que são uma coisa
completamente inexistente pra línguagens de propósito único como
PL/SQL.

Nilo Lima

unread,
Jun 16, 2009, 11:23:05 PM6/16/09
to pb...@googlegroups.com
Valeu Maurício vou dar mais uma pesquisada. Não conhecia o termo "Surrogate Keys", isso estava dificultando minha busca.

Obrigado a todos

2009/6/16 Maurício Linhares <mauricio...@gmail.com>

Rosivaldo Ramalho

unread,
Jun 17, 2009, 9:07:57 AM6/17/09
to pb...@googlegroups.com
> A lógica sobre não colocar a lógica da sua aplicação, escrita em uma
> línguagem de programação orientada a objetos é bem simples, linguagens
> de programação de uso genérico orientadas a objeto são muito mais
> flexíveis, fáceis de manter e alterar do que linguagens como PL/SQL,
> que é uma linguagem desenvolvida com um único uso em mente. Pior,
> usando uma linguagem como Java você tem todo um suporte de IDEs e
> ferramentas complementares, como controle de versão, que são uma coisa
> completamente inexistente pra línguagens de propósito único como
> PL/SQL.

Cara, gosto muito de java, mas no fim, lá no meio da sua classe mais
simples, você vai ter if, else, while e for. Instruções de controle de
fluxo como em qualquer outra linguagem estruturada. Então, se for uma
coisa complexa como um cálculo de folha de pagamento, não existe
problema algum em se utilizar uma linguagem estruturada.

Existem N+1 problemas que são algoritmos estruturados, coisas simples
como um bubble sort a coisas complexas como um cálculo de
transformação de fourier, então isso você vai utilizar programação
estruturada, seja em java, ou seja em PL/SQL, PG/SQL ou T-SQL. E sim,
são muito mais rápidas do que em java.

Maurício Linhares

unread,
Jun 17, 2009, 9:19:08 AM6/17/09
to pb...@googlegroups.com
No fim das contas tudo tudo vira zeros e uns, mas as questões aqui são
flexibilidade, manutenibilidade e suporte de ferramentas.

Linguagens orientadas a objeto são mais expressívas e mais fáceis de
se lidar do que linguagens estruturadas de uso específico, que são
péssimas pra qualquer coisa que não seja o seu objetivo, que é tratar
de tabelas.

-
Maurício Linhares
http://codeshooter.wordpress.com/ | http://twitter.com/mauriciojr

2009/6/17 Rosivaldo Ramalho <rosi...@gmail.com>:

Rafael Ponte

unread,
Jun 17, 2009, 9:32:29 AM6/17/09
to pb...@googlegroups.com
@Rosivaldo,

Se por algum motivo a performance ou complexidade do algoritimo for algo critico em certo momento então não há problemas em deixar determinada lógica de negócio no banco. Contudo, não faça da exceção a regra.

Como o Maurício falou, linguagens de propósito geral orientadas a objetos são bem mais flexíveis e principalmente expressivas. Facilitam a manutenção da aplicação e com toda certeza será bem mais fácil encontrar profissionais no mercado que dominam a linguagem :-)

@Nilo

Utilizar composite keys com um ORM como JPA/Hibernate é algo que realmente dá muito trabalho durante o desenvolvimento. Faça de tudo para convence-los a evitarem isso, pois caso contrário você (e a equipe de desenvolvedores, claro) terá inúmeras dores de cabeça.

2009/6/17 Maurício Linhares <mauricio...@gmail.com>



--
Rafael Ponte
http://www.rponte.com.br

Clovis Leoncio Junior

unread,
Jun 17, 2009, 9:42:09 PM6/17/09
to pb...@googlegroups.com

   Cara.... Você "terá" que criar chaves compostas ficou forte. Até hoje eu não vi nenhum caso, nenhumzinho sequer, em que não desse pra resolver o problema com um índice único e uma chave incremental.

   Sobre o uso de chave composta eu vou mais longe. Prefiro não usar campos de negócio como chave na maioria das minhas tabelas, mesmo que seja uma coluna só. Passei por um caso onde um sistema legado utilizava o número do processo como chave primária. Bacana até aí. De repente acontece que o número do processo passaria a ser o mesmo na primeira e segunda instância, ou seja, passei a ter dois processos com o mesmo número o que mandou pro espaço minha PK.

2009/6/16 Rosivaldo Ramalho <rosi...@gmail.com>


Dependendo da tua regra de negócio você terá que criar chaves
compostas, cabe a você a aos outros desenvolvedores ver se isso é o
que vocês necessitam.





--
Clovis Leoncio Junior

Maurício Linhares

unread,
Jun 17, 2009, 9:45:08 PM6/17/09
to pb...@googlegroups.com
É incrível como sempre que agente usa um campo do próprio dado como
chave primária isso sempre acontece ;)


2009/6/17 Clovis Leoncio Junior <clovis...@gmail.com>:

Nilo Lima

unread,
Jun 18, 2009, 6:24:17 PM6/18/09
to pb...@googlegroups.com
Olá Clóvis,

Vou te dar um exemplo que seria bem difícil com um "índice único" como vc falou.
Digamos que temos uma tabela de Funcionarios, ela tem um "índice único".
Temos a tabela de Filiais também com "índice único".

Agora temos que ligar filiais com funcionarios. Ótimo podemos colocar um "índice único" como chave mas se precisarmos fazer uma replicação merge e um dos sitios ficar fora do ar por algum tempo, quando ele voltar e tentar replicar os registros inseridos antes da queda do sitio. Problema com chaves duplicadas.

Nunca passei com esse problema, mas ele pode acontecer.

Obrigado pela colaboração.

2009/6/17 Clovis Leoncio Junior <clovis...@gmail.com>

alecindro

unread,
Jun 18, 2009, 10:09:30 PM6/18/09
to pb...@googlegroups.com
Chaves compostas = integridade do banco.
 
Quem tem de manter a integridade do banco é o próprio banco e não a aplicação. Se é difícil trabalhar com chaves compostas e hibernate, troca o hibernate por outra tecnologia. Aliás, das tecnologias hoje existentes o hibernate é a mais sofrível em termos de desempenho, mesmo com JPA.
 
Lembrem-se. A parte mais importante de um sistema são os dados. Por isso a integridade é importante.
 
Vou dar um exemplo:
 
Software para construção civil.
 
1 condomínio contém blocos que contém apartamentos. Temos aptos 101 em todos os blocos. Como identificar 1 apartamento? Chave composta, com No.
do apto e chave do bloco. E não existe nenhuma necessidade de chaves artificiais. Já os blocos precisam também ser compostas, pois podemos ter diversos condomínios com blocos "A". A tabela blocos é composta por uma chave identificando o bloco (que pode ser o próprio A) e a chave do condomínio.
 
E digo mais uma: Evite usar chaves artificiais, procure usar chaves naturais. Com meus 16 anos de analista, o maior uso do banco de dados são realizados para relatórios e pesquisas atrás de informações, com raras exceções. Se utilizar chaves artificiais, terá de indexar os atributos de maior pesquisa, gerando maior processamento do banco de dados, maior lentidão de resposta.
 
Além disso, procure realizar pesquisas com código SQL, e mande o banco processar. O banco é otimizado para isso. Onde colocar o código SQL? Pode ser em uma procedure no banco de dados, pode ser em Queries no código java.
 
E por último: Quando existe a necessidade de a mesma pesquisa se repetir diversas vezes ao longo do tempo, crie views. Views para o hibernate é como se fosse uma tabela de dados normal.
 
Já trabalhei com jdbc, JDO e no momento trabalho com JPA como tecnologia de persistência de dados. Como provedor do JPA aconselho o TopLink Essentials, hoje EclipseLink. Extremamente mais rápido que o Hibernate. Estou agora estudando tecnologias de banco de dados orientado a objetos e  tenho me surpreendido  bastante.
 
Att,
 
Alecindro
 
 

From: Nilo Lima
Sent: Thursday, June 18, 2009 7:24 PM
Subject: [PBJUG] Re: Chave primária única x Chave primária composta

Olá Clóvis,

Vou te dar um exemplo que seria bem difícil com um "índice único" como vc falou.
Digamos que temos uma tabela de Funcionarios, ela tem um "índice único".
Temos a tabela de Filiais também com "índice único".

Agora temos que ligar filiais com funcionarios. Ótimo podemos colocar um "índice único" como chave mas se precisarmos fazer uma replicação merge e um dos sitios ficar fora do ar por algum tempo, quando ele voltar e tentar replicar os registros inseridos antes da queda do sitio. Problema com chaves duplicadas. aç

Maurício Linhares

unread,
Jun 18, 2009, 10:44:45 PM6/18/09
to pb...@googlegroups.com
2009/6/18 alecindro <alec...@inf.ufsc.br>:

> Chaves compostas = integridade do banco.
>
> Quem tem de manter a integridade do banco é o próprio banco e não a
> aplicação. Se é difícil trabalhar com chaves compostas e hibernate, troca o
> hibernate por outra tecnologia. Aliás, das tecnologias hoje existentes o
> hibernate é a mais sofrível em termos de desempenho, mesmo com JPA.
>
> Lembrem-se. A parte mais importante de um sistema são os dados. Por isso a
> integridade é importante.
>

A parte mais importante do sistema depende de cada sistema,
simplificar assim é muito perigoso :)

Quanto a integridade dos bancos de dados, ela não tem nada haver com
chaves compostas, mas com índices únicos colocados nas colunas
corretas.

> Vou dar um exemplo:
>
> Software para construção civil.
>
> 1 condomínio contém blocos que contém apartamentos. Temos aptos 101 em todos
> os blocos. Como identificar 1 apartamento? Chave composta, com No.
> do apto e chave do bloco. E não existe nenhuma necessidade de chaves
> artificiais. Já os blocos precisam também ser compostas, pois podemos ter
> diversos condomínios com blocos "A". A tabela blocos é composta por uma
> chave identificando o bloco (que pode ser o próprio A) e a chave do
> condomínio.
>
> E digo mais uma: Evite usar chaves artificiais, procure usar chaves
> naturais. Com meus 16 anos de analista, o maior uso do banco de dados são
> realizados para relatórios e pesquisas atrás de informações, com raras
> exceções. Se utilizar chaves artificiais, terá de indexar os atributos de
> maior pesquisa, gerando maior processamento do banco de dados, maior
> lentidão de resposta.
>

Qualquer manual de banco de dados vai explicar que chaves inteiras,
crescentes e contíguas são as que vão lhe fornecer a melhor
performance em consultas e indexação. É exatamente por esse motivo que
os diversos manuais de melhoria de performance em bancos de dados vão
lhe dizer que a melhor chave primaria pra sua tabela é uma coluna com
um número inteiro e auto incrementado, a chave artificial mais comum
que existe.

Chaves não numéricas e/ou crescentes vão ser sempre mais lentas e
sempre mais trabalhosas de se lidar, pois elas não são contíguas e não
é fácil para o banco "chutar" a provável posição dela em um índice sem
ter que fazer um passeio grande por ele.

E ainda tem a melhor parte, depois de perder performance, na hora que
você precisar trocar o nome do bloco do apartamento, já viu né?
Dançou.

> Além disso, procure realizar pesquisas com código SQL, e mande o banco
> processar. O banco é otimizado para isso. Onde colocar o código SQL? Pode
> ser em uma procedure no banco de dados, pode ser em Queries no código java.
>
> E por último: Quando existe a necessidade de a mesma pesquisa se repetir
> diversas vezes ao longo do tempo, crie views. Views para o hibernate é como
> se fosse uma tabela de dados normal.
>
> Já trabalhei com jdbc, JDO e no momento trabalho com JPA como tecnologia de
> persistência de dados. Como provedor do JPA aconselho o TopLink Essentials,
> hoje EclipseLink. Extremamente mais rápido que o Hibernate. Estou agora
> estudando tecnologias de banco de dados orientado a objetos e  tenho me
> surpreendido  bastante.

Você poderia nos mostrar os benchmarks que comprovam que o EclipseLink
é mais rápido que o Hibernate?

Maurício Linhares

unread,
Jun 18, 2009, 10:49:23 PM6/18/09
to pb...@googlegroups.com
Esse problema normalmente é resolvido com uma ferramenta
"personalizada" de resolução de conflitos e chaves primárias de
VARCHAR geradas por UUIDs, não é um caso nem um pouco trivial nem
comum de se lidar.

Se você se basear sempre pelo pior caso, vai terminar nunca terminando
o que havia pra fazer de verdade.

2009/6/18 Nilo Lima <nilo.a...@gmail.com>:

Maurício Linhares

unread,
Jun 18, 2009, 10:50:15 PM6/18/09
to pb...@googlegroups.com
Outra coisa, pra quem nunca se preocupou em entender ou fazer análise
de performance de bancos de dados, recomendo fortemente a leitura do
livro "High Performance MySQL", é um tanto quanto específico pro MySQL
mas mesmo assim contém muitas dicas sobre performance de bancos de
dados no geral - http://oreilly.com/catalog/9780596101718/

alecindro

unread,
Jun 18, 2009, 10:55:38 PM6/18/09
to pb...@googlegroups.com
Sempre a parte mais importante são os dados. Já perguntou a algum cliente se
tem algum problema perder os dados?

Em uma empresa a coisa mais valiosa são os dados. Se os dados não são
importantes não existe necessidade de banco de dados. Use outra tecnologia.

--------------------------------------------------
From: "Maurício Linhares" <mauricio.linhares@gmam>
Sent: Thursday, June 18, 2009 11:44 PM
To: <pb...@googlegroups.com>
Subject: [PBJUG] Re: Chave primária única x Chave primária composta

>

alecindro

unread,
Jun 18, 2009, 11:08:00 PM6/18/09
to pb...@googlegroups.com
A chave composta só existe para manter a integridade do banco de dados.
Senão não teríamos a necessidade de tal.
Acontece muito quando tenho uma relação entre duas tabelas n x n.
Eu não consigo ter um índice único com apenas uma chave, mas a combinação
das duas chaves deve ser única.


--------------------------------------------------
From: "Maurício Linhares" <mauricio...@gmail.com>
Sent: Thursday, June 18, 2009 11:44 PM
To: <pb...@googlegroups.com>
Subject: [PBJUG] Re: Chave primária única x Chave primária composta

>

alecindro

unread,
Jun 18, 2009, 11:30:13 PM6/18/09
to pb...@googlegroups.com
Não vi a parte da troca do nome do bloco. É só criar uma nova linha na
tabela bloco e atualizar os apartamentos onde estava com esse bloco. Não vou
criar milhares blocos com o mesmo nome, sendo que o nome do bloco se repete
em muitos edifícios. A questão do bloco foi só um exemplo, de repente não o
melhor.

Em relação a chave artificial x natural eu acharia interessante tu estudar
melhor a forma de trabalho dos banco de dados.

Creio que você quis dizer que é mais fácil trabalhar orientado a objeto com
chaves artificiais incrementais.

Mas não esqueça que dados são apagados e buracos vão ficando no meio dos
indíces artificiais autoincrementeais.

Indico a quem desejar se aprofundar, essas listas de discussão própria de
quem trabalha com banco de dados:

http://listas.postgresql.org.br/cgi-bin/mailman/listinfo
http://lists.mysql.com/
http://br.egroups.com/group/GPOracle



--------------------------------------------------
From: "Maurício Linhares" <mauricio...@gmail.com>
Sent: Thursday, June 18, 2009 11:44 PM
To: <pb...@googlegroups.com>
Subject: [PBJUG] Re: Chave primária única x Chave primária composta

>

Maurício Linhares

unread,
Jun 18, 2009, 11:50:58 PM6/18/09
to pb...@googlegroups.com
2009/6/19 alecindro <alec...@inf.ufsc.br>:

>
> Em relação a chave artificial x natural eu acharia interessante tu estudar
> melhor a forma de trabalho dos banco de dados.
>
> Creio que você quis dizer que é mais fácil trabalhar orientado a objeto com
> chaves artificiais incrementais.
>

Não :)

O que eu quis dizer foi exatamente exatamente o que estava escrito,
chaves inteiras, crescentes e contíguas são melhores do que chaves não
crescentes e não contíguas.

Mais uma vez, recomendo a leitura do "High Performance MySQL",
especialmente o capítulo 3 que trata de indexação e otimização de
schemas.

Tomaz Lavieri

unread,
Jun 19, 2009, 6:43:06 AM6/19/09
to pb...@googlegroups.com
Aproveitando o animo de vocês nessa discussão ^^, e mudando um pouco o
foco para EJB, como vocês costumam identificar suas Entitys
(especificamente falando de equals/hashcode)?

1° uma observação: eu uso chave primária interna não composta (que não
faz parte da lógica de negocio)

Eu não uso a chave primária para os testes de equals e na geração de
hashCode, não faço isso para poder comparar objetos não persistentes
com objetos persistentes, e para não bugar as tabelas hashs (pois caso
o equals/hashCode seja baseado na chave primária gerada por
auto-incrase o hashCode vai mudar após a persistência bugando as
tabelas hash).

Como vocês costumam implementar o equals/hashCode nos EJBs? baseado na
chave-primária ? baseado em um campo único que faz parte da lógica de
negocio ?

2009/6/19 Maurício Linhares <mauricio...@gmail.com>:
--
Tomaz Lavieri
Sun Certified Java Programmer (SCJP 6)

meu blog => http://java-i9se.blogspot.com/

Maurício Linhares

unread,
Jun 19, 2009, 7:31:28 AM6/19/09
to pb...@googlegroups.com
Se há chaves primárias nos dois objetos comparados, eu uso as chaves
primárias pra comparação, se não há chaves primárias definidas nos
dois, eu uso os dados do objeto.

2009/6/19 Tomaz Lavieri <tomazl...@gmail.com>:

Tomaz Lavieri

unread,
Jun 19, 2009, 7:53:34 AM6/19/09
to pb...@googlegroups.com


2009/6/19 Maurício Linhares <mauricio...@gmail.com>


Se há chaves primárias nos dois objetos comparados, eu uso as chaves
primárias pra comparação, se não há chaves primárias definidas nos
dois, eu uso os dados do objeto.

Mas isso não iria de encontro as regras de equals ?? pios você pode ter um caso onde

A com id = 10 ... e campo lógico único = "X"
B com id = 10 ... e campo lógico único = "Y" (objeto para ser alterado)
C sem id - ---- ... e campo lógico unico = "Y"

A == B, B == C .... porem A != C (Pois como C não tem ID você testaria pelo campo lógico), e segundo as regras do equals isso quebraria a tranzitividade do equals e que não deveria ocorrer.

o outro ponto é o hashCode que deve seguir a lógica do equals, e sem ID a lógica do equals é uma, então o hashCode tem que seguir esta lógica, após persistir a lógica muda e o equals vai ser realizado por ID e portanto o número do hashCode vai mudar.

o problema de mudar um hashCode durante a vida do objeto, é que se ele estiver dentro de um coleção hash, o objeto não poderá mais ser encontrado dentro da coleção...

Isso causa bugs quando você persiste um objeto que faz cascade em uma coleção dele

...........

Para contornar esse problema o que você faz ?? você ta usando Lists para os relacionamentos 1-N ?? (acredito que nenhuma implementação de List use tabelas hash) .... porque trocar o hashCode de um objeto dentro de um hashSet ou hashMap causa problemas gravíssimos, e usando a abordagem que você falou há um impedimento de consistência de se usar coleções hash em qualquer parte da aplicação...



2009/6/19 Tomaz Lavieri <tomazl...@gmail.com>:
>
> Aproveitando o animo de vocês nessa discussão ^^, e mudando um pouco o
> foco para EJB, como vocês costumam identificar suas Entitys
> (especificamente falando de equals/hashcode)?
>
> 1° uma observação: eu uso chave primária interna não composta (que não
> faz parte da lógica de negocio)
>
> Eu não uso a chave primária para os testes de equals e na geração de
> hashCode, não faço isso para poder comparar objetos não persistentes
> com objetos persistentes, e para não bugar as tabelas hashs (pois caso
> o equals/hashCode seja baseado na chave primária gerada por
> auto-incrase o hashCode vai mudar após a persistência bugando as
> tabelas hash).
>
> Como vocês costumam implementar o equals/hashCode nos EJBs? baseado na
> chave-primária ? baseado em um campo único que faz parte da lógica de
> negocio ?
>


Maurício Linhares

unread,
Jun 19, 2009, 8:26:43 AM6/19/09
to pb...@googlegroups.com
Opa Tomaz,

Digamos que eu tenha três objetos, um objeto raiz A e dois objetos
relacionados, através de um relacionamento N:N, B e C.

B já está persistido no banco e tem um id 10 e um nome "B", C ainda
não está persistido mas tem um nome "C".

O objeto A é persistido e C recebe um id 11 quando isso acontece. Em
um momento posterior, eu busco o objeto B no banco de dados, troco o
seu nome por "D", salvo a alteração no banco e vou até o conjunto [B,
C] relacionado a A pra saber se esse meu B, com nome "D" já está no
banco. Como o meu equals e hashCode funcionam através da comparação do
nome e desconsidera a chave primária, esse "novo" objeto vai ser
adicionado a coleção normalmente, mesmo que ele já esteja adicionado a
ela com uma propriedade diferente.

No fim das contas, quem diz a identidade "real" do objeto é a chave
primária, não as suas propriedades. E alterar o modo de geração de
hashCodes de um objeto quando ele já está dentro de uma coleção que
usa tabelas de hash é sim péssimo, mas aí fica como responsabilidade
de quem programou ou descartar a coleção "incorreta" ou a reconstruir
com os objetos no novo estado. O re-hash é uma operação comum sempre
que você faz alterações nas propriedades que formam a identificação de
um objeto.

Rafael Ponte

unread,
Jun 19, 2009, 9:30:44 AM6/19/09
to pb...@googlegroups.com
No fim das contas, quem diz a identidade "real" do objeto é a chave
primária, não as suas propriedades

Isso pode ser até verdade para o banco, mas não necessariamente para o domínio da aplicação. Na maioria das vezes a chave primária será a identidade da sua entidade, mas há casos em que para o domínio a identidade de uma determinada entidade representa um conjunto de propriedades. Quando bem definido a identidade de uma entidade você evita problemas com equals e hashCode.


2009/6/19 Maurício Linhares <mauricio...@gmail.com>

Samuel Valerio

unread,
Jun 19, 2009, 9:51:37 AM6/19/09
to pb...@googlegroups.com
Maurício,

  A própria página do Hibernate não recomenda o uso de business/natural keys no equals/hashcode quando elas existem para a entidade em questão ?

  Referência: https://www.hibernate.org/109.html

  A referência acima mostra as problemas existentes em usar a propriedade id no equals/hascode. Ele cita inclusive um exemplo de objeto User em que o equals/hascode deveriam utilizar a propriedade username; e não o id.

  Inclusive, a ferramenta hbm2java (do próprio Hibernate), ainda pela referência acima, gerava o equals/hascode baseados no id e, devido aos problemas existentes, deixou de fazê-lo. Criaram um meta atributo para você especificar quais propriedades devem ser utilizadas na geração do equals/hascode.

Samuel Valerio


2009/6/19 Rafael Ponte <rpo...@gmail.com>

Rafael Ponte

unread,
Jun 19, 2009, 9:58:20 AM6/19/09
to pb...@googlegroups.com
Quem diz qual será a identidade de uma entidade é o domínio :-) Mas daí eu te digo, para a maioria dos caso será a própria chave primária mesmo.

2009/6/19 Samuel Valerio <samuel...@gmail.com>

Rafael Ponte

unread,
Jun 19, 2009, 10:08:17 AM6/19/09
to pb...@googlegroups.com
alecindro,

2009/6/18 alecindro <alec...@inf.ufsc.br>


Sempre a parte mais importante são os dados. Já perguntou a algum cliente se
tem algum problema perder os dados?

Como o Maurício falou, depende do cliente e sistema. Assumir isto é perigoso e equivocado.
 

CMilfont

unread,
Jun 19, 2009, 10:12:47 AM6/19/09
to pb...@googlegroups.com
Não existe apenas bancos de dados relacionais para manipulação de dados, algumas crianças ja entenderam isso

http://blog.oskarsson.nu/2009/06/nosql-debrief.html

2009/6/18 alecindro <alec...@inf.ufsc.br>



--
http://www.milfont.org

CMilfont

unread,
Jun 19, 2009, 10:14:45 AM6/19/09
to pb...@googlegroups.com
a ferramenta hbm2java gera um modelo anemico e totalmente desconselhável por qualquer profissional sério.
Se for para programar de forma relacional sua aplicação, faça direto com a linguagem do proprio SGBD que resolve melhor do que Java, se o problema for web usa uma daqualas ferramentas que geram html dos bancos...

#nomorerelacional

2009/6/19 Samuel Valerio <samuel...@gmail.com>



--
http://www.milfont.org

CMilfont

unread,
Jun 19, 2009, 10:15:42 AM6/19/09
to pb...@googlegroups.com
NInguem vai trabalhar com perda de informações do cliente, agora salientar que isso é trabalho apenas do banco e ignorar o dominio da aplicação no contexto geral é de um reducionismo perigoso

2009/6/19 Rafael Ponte <rpo...@gmail.com>



--
http://www.milfont.org

CMilfont

unread,
Jun 19, 2009, 10:19:45 AM6/19/09
to pb...@googlegroups.com
o beneficio de "chaves naturais" que é a indexação pode e deve ser compensada com surrogate + indices uniques facilmente sem comprometer a orientação a objetos da aplicação.
Agora para aplicações BOLOVO, não faz muita diferença mesmo

2009/6/19 Maurício Linhares <mauricio...@gmail.com>



--
http://www.milfont.org

CMilfont

unread,
Jun 19, 2009, 10:22:40 AM6/19/09
to pb...@googlegroups.com
banco de dados trabalham muito bem com indexação a quente nos "buracos" que vão ficando, não sei qual a preocupação. Até os banquinhos de brinquedo como o Mysql fazerm um trabalho decente...

2009/6/19 alecindro <alec...@inf.ufsc.br>



--
http://www.milfont.org

Samuel Valerio

unread,
Jun 19, 2009, 1:19:18 PM6/19/09
to pb...@googlegroups.com
Pessoal,

  Queria deixar claro que em momento algum eu aconselhei o uso da ferramenta hbm2java para gerar as classes do modelo da aplicação a partir das tabelas do banco. Acredito que ela tenha a sua utilidade: sistemas e bancos legados. Eu, inclusive, nos novos sistemas, sempre gero o banco a partir das minhas classes do modelo; e não o inverso. Justamente pra fugir do modelo anêmico[http://martinfowler.com/bliki/AnemicDomainModel.html] citado pelo Milfont.

  O meu objetivo foi citar referências do próprio Hibernate - a mudança da forma como o hbm2java trabalha foi uma delas - que recomendam o uso de chaves naturais/de negócio/do domínio para a implentação do equals e do hashcode. Não abordei o uso de chaves naturais/compostas/únicas no banco. Talvez tenha fugido do assunto do tópico; por isso couberam outras interpretações. Referi-me exclusivamente à aplicação. À implementação dos métodos equals e hashcode das classes do modelo. Questionei o uso da propriedade id no equals e no hascode. Caso seja utilizada, ocorrerão os problemas citados na referência do próprio Hibernate que indiquei[https://www.hibernate.org/109.html].

  O problema de se alterar um atributo que compõe o equals/hascode sempre vai existir, isso é inevitável. A questão é qual estratégia possui a melhor saída. Não há um consenso pelo que li. A vantagem de não utilizar id, no equals/hashcode, é que as coleções ficam consistentes mesmo após a persistência de um objeto. Entretanto, qualquer mudança em algum dos atributos que compõe o equals/hashcode poderá ocasionar inconsistência na aplicação.

<opiniaoPessoal>
  Enfim, acredito que o uso do id no equals/hashcode deve ser evitado. Acho que faz mais sentido haver uma inconsistência no estado da aplicação devido à mudança em um atributo que efetivamente faz parte do teu modelo/domínio, como nome no exemplo do Maurício, do que a atribuição de um id, que não possui valor nenhum de negócio/domínio.
</opiniaoPessoal>

  De toda forma, trabalhando com os objetos sempre no menor escopo possível, utilizando id ou não no equals/hashcode,  a possibilidade de se ter problemas nas coleções por conta disso é relativamente pequena. Não acham ?

Milfont,

  O uso do hbm2java, em princípio, gera um modelo anêmico. Entretanto, isso pode mudar. Dependerá do desenvolvedor; de como e onde ele implementa as regras de negócio/validações/cálculos. Se ele o fizer dentro das próprias classes do modelo, acho já fica menos anêmico. Você não acha ?

[]'s

Samuel Valerio


2009/6/19 CMilfont <cmil...@gmail.com>

Rafael Ponte

unread,
Jun 19, 2009, 1:29:03 PM6/19/09
to pb...@googlegroups.com
De toda forma, trabalhando com os objetos sempre no menor escopo possível, utilizando id ou não no equals/hashcode,  a possibilidade de se ter problemas nas coleções por conta disso é relativamente pequena. Não acham ?

Sim, são bem remotas as chances. Não vejo motivos em se ficar alterando a identidade de um objeto durante um determinado procedimento que envolve collections ou não. Não digo todos os casos, mas na grande maioria das vezes isso será um problema criado pelo desenvolvedor.

2009/6/19 Samuel Valerio <samuel...@gmail.com>

alecindro

unread,
Jun 20, 2009, 3:27:05 PM6/20/09
to pb...@googlegroups.com
Não quis em nenhum momento dizer que isso é trabalho apenas do banco.
Há casos em que não dá. Mas sempre que possível o banco não deve permitir inconsistências.
Se for apenas para armazenar dados de temos outros meios muito mais ágeis.
O delay da transformação do paradigma da orientação a objeto para o paradigma relacional tem custo alto.
Reply all
Reply to author
Forward
0 new messages