Estou estudando DDD e tentando aplicar conceitos em uma implementação teste e tenho a seguinte dúvida:
Segundo a literatura (Eric Evans), um [b]Value Object/b é um objeto onde o que importa é o seu valor, ou seja, todos os atributos identificam a identidade do objeto e não um único ID como por exemplo Pedido, Pessoa, ou outra [b]Entity/b.
Considerando duas classes simples, Pessoa e Endereço onde no meu entendimento Pessoa é um Entity e Endereço um Value Object (Pois podem 2 pessoas morarem no mesmo endereço e o que identifica o endereço são todos seus atributos), seguem alguns questionamentos:
[list]Após persistido, como eu recupero esse Endereco no banco se não tem um ID ? vou ter que comparar todos os campos na query ?[/list]
[list]Como Value Object teoricamente não tem ID, como na hora de persistir vai ficar registrado no BD que a Pessoa mora naquele Endereco?[/list]
[list]Vou ter que criar uma constraint no Banco com todos os campos para evitar duplicidade de Endereco ? Qual seria uma outra forma de garantir que não serão incluidos 2 Value ObjectsEndereco iguais?[/list]
[list]E no com hibernate como que fica pra recuperar e garantir que não serão incluidos 2 Value ObjectsEndereco iguais já que não tem ID ?[/list]
Pelo que eu tenho lido a respeito e aplicado, o Value Object é recomendado para uso quando vc tem uma aplicação em ambiente distribuido em mais que 1 JVM, pois você recupera um Entity como objeto persistente, o transforma em transiente, usando o VO.
Leia este tutorial que pode te dar uma idéia de como usá-lo, se realmente vc precisar usá-lo.
Opa!
Value Object é um objeto simples nao referenciado… um “agrupado” de atributos que juntos identificam alguma coisa no sistema…
No banco um value object pode ateh ser um type (mas nao sei como ficaria isso pro hibernate, nesse caso uma tabelinha ia bem)… depende do que quer fazer… eu nao definiria endereco como um value object, não acho endereco uma classe assim tao simples… (logradouro ateh q poderia, pq a primeira vista soh teria tipo, descricao e numero)
o lance da constraint para evitar repeticao tmb é um fato… se nao quer q repita vai ter q colocar lah… mas e aih, como fica se cadastrar duas pessoas com o mesmo endereco, vai apontar para o mesmo registro??? nao sei se rola, pq se fizer isso qdo alterar o endereco do primeiro vai alterar o do segundo tmb… fazer o q, enderecos podem repetir…
por essas eu vejo q um id vai bem e endereco nao seria simplificado como um value object…
abraco
S
sergiotaborda
Primeiro ha que esclarecer a diferença entre VO do DDD e VO fora do DDD.
Value Object é muito usado como sinónimo de DTO (Data Transfer Object) especialmente quando
não se trata de transferencia entre nodos mas apenas entre camadas. Neste significado VO é um objeto relacionado a arquitectura do sistema.
Todo o mundo entendia isto até que o senhor Fowler dicidir usar Value Object para identificar
objecto imutável que contém um valor. Esta categoria de objetos que incluem , por exemplo, String, Number, Date - e outros como Money - e não tem nada a ver com os DTO. Neste significado VO é um objeto relacionado a modelagem.
Em DDD Value Object é entendido com o significado dado por Fowler e não com o significado sinónimo de DTO.
Então é preciso ter muito cuidado quando se fala de Value Object.
O emerleite falou explicitamente dos VO do DDD que são objetos em nada relacionados aos DTO e aos problemas arquitecturais.
dito isto, é preciso esclarecer que o colega emerleite não apanhou completamente o conceito de VO.
Não é bem verdade isto. Aliás é verdadeiramente o inverso.
O VO é um objeto onde o que importa é o seu valor, ou seja, ele não tem identidade.
Em outras palavras VO é o valor que um campo da identidade assume e que não se refere a outra entidade.
Exemplos: nome, datas , quantidades (monetárias ou métricas) , unidades, categorias, codigos (CEP,CNPJ…).
Endereço e um bom exemplo de caso dubio. Como o ppr Evans explica, Endereço será uma entidade se o sistema precisa controlo do endereço de forma independente do resto dos objetos. Num sistema de correio o endereço é a entidade principal. Cada endereço tem que ser identificado no sistema para que a correspondencia possa seguir seu caminho. Num sistema de contas a pagar o endereço do cliente é uma mera informação associada ao cliente ( é um campo de cliente) onde o endereço nunca é tratado de forma separada do cliente a quem pertence.
No primeiro sistema, endereço terá sua tabela propria com chaves e tudo o mais. No segundo, endereço será um conjunto de campos na tabela de cliente, que quando o cliente é lido são aglomerado no objeto diferente
em codigo
public Cliente getClienteById( int ID){
ResultSet rs = dao.executaQueryNativa ("Select * from cliente where cliente_id = ?" , ID);
rs.next();
Cliente c = new Cliente(ID);
c.setNome(rs.getString("nome"));
c.setNascimento( rs.getDate("nascimento"))); // o objeto Date é um VO (padrão java)
c.setCNPJ( new CNPJ(rs.getString("cnpj"))); // o objeto CNPJ é um VO (não-padrão do java)
Endereco ed = new Endereco();
ed.setLogradouro (rs.getString("logradouro"));
ed.setCEP(new CEP(rs.getString("cep"))); // o objeto CEP é um VO (não-padrão do java)
ed.setNumero(rs.getString("numero"));
ed.setComplemento(rs.getString("complemento"));
c.setEndereco(ed);
return c;
}
Não existe tabela endereço, mas existe objeto Endereço. Isso caracteriza um VO. Um VO não precisa de tabela propria (embora possa ter uma). Uma entidade tem que ter uma tabela própria.
Outro exemplo. Pedido e Item. O item não existe sem um pedido e não pode ser transferido entre pedidos.
O item não tem uma identidade per se, ele sempre necessita estar ligado a um pedido. então pedido é uma entidade e item é um VO. Neste caso Item terá a sua propria tabela porque a relação pedido-item é um-para-muitos, mas apenas por isso, e não porque é uma entidade. Em termos de banco o Id do item é composto por um numero + o id do pedido.
Produtop=...Itemit=newItem(p,34);Pedidoa=newPedido();a.add(it);// okPedidob=newPedido();b.add(it);// erro : O item já está associado a outro pedido// controlo dentro de pedidopublicvoidadd(Itemitem){if(item.getPedido()==null){item.setPedido(this);listadeItens.add(item);}thrownewIllegalAgumentException(Oitemjáestáassociadoaoutropedido);}
Quanto ao problema de duplicar endereços.
Se A e B vivem no mesmo endereço A e B são a mesma pessoa ? não.
Então é possível existir duplicação de endereços e endereço não é uma entidade, é um VO.
Espero que seja mais claro o papel do VO no DDD e sua diferença do VO comum
E
Emerson_Macedo
Marcio, vc se enganou pois o Value Object que estou falando é o catalogado pelo Eric Evans e Martin Fowler que nada tem a ver com o antigo da Sun que já mudou de nome para Transfer Object e Fowler catalogou como Data Transfer Object.
Mas Endereco não seria identificado apenas pelos seus atributos diferente de Pessoa que por um CPF se identifica já que não pode se repetir ?
Eu entendi que se o endereço mudasse já não seria o mesmo Value Object e sim outro, consequentemente quando fosse persistir seria gravado um outro Endereco e apontando pra esse.
Endereco então seria um Entity ? Não consegui ver dessa maneira. Talvez esteja faltando ainda pra mim algum entendimento a mais sobre o assunto. Se alguém puder esclarecer …
Faltou dizer como ficaria o relacionamente entre eles no BD após persistir caso Endereco seja Value Object vc sabe ?
S
sergiotaborda
Identificar é diferente de encontrar. CPF não identifica a pessoa. A identidade da pessoa não é convertivel em bytes. Por isso temos subterfurgios como o RG e o CPF. O conceito é que cada CPF é de uma pessoa e cada pessoa tem um CPF, mas esta regra comum é falseável. (um bandido que é uma pessoa tem varios CPF …ou nenhum conforme se veja). Então CPF não identifica a pessoa. RG idem.
Os codigos de identificação podem mudar (CGC -> CPF). Isso não significa que a pessoa mudou.
O que identifica a Pessoa ? O que faz uma pessoa ser diferente de outra pessoa não é o que identifica a pessoa.
O que identifica a pessoa é a pessoa em si. :lol: bom, Identidade é um conceito matemático. Ou se entende ou não se entende.
Não é possivel colocar a identidade em bits , por isso é necessário criar artficios. usar codigos identificadores não é boa ideia. O bom é usar um numero sequencial unico no sistema, não alterável dado no momento em que a pessoa é pela primeira vez "manipulada" pelo sistema. Se esse numero é o mesmo, a pessoa é a mesma. tudo o resto pode mudar. todos os atributos podem mudar, mas a sua identidade nunca mudará.
Claro que uma dos atributos da Pessoa será o CPF, mas ele serve para procurar e encontrar a pessoa e não para a identificar.
O conceito de identidade é muito complexo , e simples ao mesmo tempo e é essencial para entender o que o DDD chama de Entity.
E
Emerson_Macedo
Sergio,
Obrigado pela ajuda mas acho que vocë não entendeu o ponto ou eu não expliquei direito.
sergiotaborda:
Num sistema de contas a pagar o endereço do cliente é uma mera informação associada ao cliente ( é um campo de cliente) onde o endereço nunca é tratado de forma separada do cliente a quem pertence.
No primeiro sistema, endereço terá sua tabela propria com chaves e tudo o mais. No segundo, endereço será um conjunto de campos na tabela de cliente, que quando o cliente é lido são aglomerado no objeto diferente
em codigo
O meu caso é justamente o segundo e eu não sabia que mesmo com N pessoas no mesmo endereço eu iria repetir a informação de endereço no BD. Pelo que eu entendi que você falou sim e seriam campos da tabela pessoas. Me entenda que eu estou apenas tentando entender como é a implementaçào na prática e não comparando modelo OO com relacional, mas no fim das contas temos que implementar a persistência disso e então saber como fazer da maneira correta.
Um value object pode ter esse id (que você ta chamando de número) que não serve pra nada ?
No Brasil sim
Me explique melhor essa.
Te agradeço. Está agregando bastante
Y
YvGa
Eu acho q o Endereco se enquadra sim no chamado Value Object. Por mais q mais de uma pessoa possa morar no mesmo endereco ele continua sendo uma informacao unica a entidade. Um endereco solto (claro q isso dependendo da abordagem e da finalidade do que se esta fazendo) um endereco solto nao faz sentido algum.
Agora na pratica, pelo menos o hibernate normalmente trata o VO como “component”. Todas as informacoes sao mapeadas para a mesma tabela. Por ex: A tabela cliente vai ter o Id, nome, cpf etc, e mais o campos do objeto Endereco.
S
sergiotaborda
Não. Não pode. Se tiver ele passa a ser uma Entity.
Se o seu caso é aquele em que os campos relativos a endereço estão no mesmo registro que os de cliente, então eu já exemplifiquei como implementa. Vc lê todos os campos de uma vez e depois divide em objectos vai incorporando no objeto Cliente. Quando for gravar , vc faz o contrário, lê todos os campos , inclusive os do objecto endereço e joga na mesma frase do updade. A chave do update será o ID do cliente. Vc nunca precisará de um ID para o endereço.
Como disse, Identidade não é conversível em bytes, nem em papel , nem em nada.
Por isso vc tentar identificar a pessoa com marcadores que supostamente são unicos como impressão digital, retina , veias no dedo , DNA ou o CPF …
Entenda que tudo isso são attributos da pessoa e não representam a pessoa em si, portanto não são a identidade da pessoa, são apenas marcadores únicos.
A prova de que a identidade não está no CPF é que os bandidos têm vários
J
JimMorrison
CPF é uma chave lógica q foi inventada para simplificar a identificacao de pessoas, assim como o CEP para enderecos.
Eh interessante reconhecer a chave natural de uma entidade(no caso do endereço foi visto q a chave natural envolveria todos os campos), decidir fazer dela uma chave unica já é um outro passo…
Usar um identificador significa trocar a equivalente chave natural por uma logica, que pode ser uma padronizada (CPF, CEP, RG, etc) ou um ID do sistema (um sequencial da vida) para identificar um determinado registro e evitar repeti-lo.
Tah, mas e aih, no caso do endereco, de que isso me interessa? se a relacao entre pessoa e endereco é de 1 para 1, nada… Pessoa entao deve ter os atributos de endereco
Se a relacao eh de um pra muitos… aih comeca a importar, pois terei q buscar os enderecos de alguma forma e identifica-los (seja por chave natural ou logica). Se eu preciso dizer no sistema quais os enderecos de uma determinada pessoa nao vou querer passar todos os campos do endereco pra isso, a chave logica vai bem…
Se a relacao é de muitos pra muitos aih tem q pensar no problema de enderecos orfaos… de alterar um endereco de alguem e por consequencia de outra pessoa relacionada 'aquele endereco, tem quem faca disso um motivo para chave primaria composta no banco e mais um monte de problemas…
Enfim… eu prefiro repetir enderecos… uma pessoa um endereco… ou, se necessario, uma pessoa muitos enderecos.
Qdo disse que endereco nao é uma classe simples foi por ter muitos atributos, tipo de logradouro (rua, av., etc) , descricao, numero, complemento, cep, cidade, estado…
É viajem ficar imaginando alguma operacao pra essa classe, nao conheco o seu sistema e nunca usei nenhuma operacao relacionada ao endereco (receberPostagem ou algo do tipo) cabe a voce saber se pode ter alguma coisa do tipo… se tiver, esquece VO (mas como fez o dever de casa e eu acho q entendeu sim o conceito de VO jah deve saber disso)
Se voce fizer do endereco um VO vai estar atrapalhando o encapsulamento de Pessoa ??? divindo atributos q sao da pessoa com uma classe Endereco… O que voce ganha fazendo de Endereco um VO? VO = TIPO
E
Emerson_Macedo
Eu entendi mas isso contradiz um pouco o que vê disse no post anterior dizendo que Item era um VO mas que item tinha um ID
Ok isso eu sei mas o importante era saber se ia duplicar o endereço. Pelo que eu entendi duplica. Obrigado
Ok mas dentro de um domínio de um sistema, Uma entidade de uma pessoa fisica pode sempre ser identificada pelo CPF que é unico e nesse caso o que impede do CPF ser a identidade da pessoa ?
S
sergiotaborda
Eu entendi mas isso contradiz um pouco o que vê disse no post anterior dizendo que Item era um VO mas que item tinha um ID
Eu disse "Em termos de banco o Id do item é composto por um numero + o id do pedido. "
Ou seja, no banco vc vai ter uma coluna chamada “numero” e outra chamada “pedido_id” e os dois são a chave (o id em termos de banco) do VO no banco.
Em objetos o VO não terá informação do ID do pedido e sim uma referencia ao objeto Pedido. O VO terá internamente o attributo “numero” mas ele será imutável. Nada disto caracteriza a identidade do VO.
A coluna “numero” a que me referi no texto original era para fornecer um mecanismo de IDENDITDADE, esta coluna “numero” a que me refiro aqui é um mecanismo de CONSISTENCIA só para que ao gravar o item de volta vc possa fazer um update e não um insert. São coisas diferentes. Vc perguntou se o “numero” para fornecer identidade poderia ser usado no VO, a reposta é “não” porque eles não servem o mesmo objetivo.
[adicionado]
A diferença é na hora de implementar equals Item.equals(item) sse todos os campos são os mesmos e não se idpedido+numero é igual
Uma entidade terá um método isSameAs() que compara o numero de IDENDITDADE apenas.
[adicionado]
Pense um momento: ‘A’ e ‘A’ são duas representações da mesma coisa, ou são a mesma coisa representada duas vezes ?
.
.
.
Se são duas representações da mesma coisas, então ‘A’ é um valor.
Se são a mesma coisas representada duas vesez , então ‘A’ é uma entidade
“Rua do Aroche , 10 apt 90” e “Rua do Aroche , 10 apt 90” são são das hipoteses ? 8)
T
TheMask
Hã? Duas representações da mesma coisa é equivalente a ter a mesma coisa representada duas vezes. :lol:
João têm as duas filhas ou as duas filhas são de João? :roll:
E
Emerson_Macedo
A minha dúvida sempre foi no Banco por isso que eu perguntei como que fica no Banco. Um VO não teria ID mas eu havia entendido que na hora de persistir no caso do Item haveria um ID no banco para poder relacionar com o Pedido.
Isso é basico em OO e eu sei. A questão é só na hora de persistir
sergiotaborda:
Pense um momento: ‘A’ e ‘A’ são duas representações da mesma coisa, ou são a mesma coisa representada duas vezes ?
.
.
.
Se são duas representações da mesma coisas, então ‘A’ é um valor.
Se são a mesma coisas representada duas vesez , então ‘A’ é uma entidade
“Rua do Aroche , 10 apt 90” e “Rua do Aroche , 10 apt 90” são são das hipoteses ?
Concordo. Novamente a questão é na hora de persistir se seria correto duplicar o mesmo endereço sendo que uma mesma pessoa pode morar naquele endereço. Pelo que eu entendi devemos duplicar. Valeu pelo esclarecimento.
B
BiraBoy
Estou aproveitando este tópico antigo para não criar um novo.
Gente, como se trata um Value Object (DDD, catalogado por Fowler e Evans) num mapeamento de hibernate?
Ah, poderíamos tomar como base os exemplos de value object do Shoes na revista Mundo Java 17(OO com padrões de negócio). Como ficaria o Value Object Categoria e o Moeda num mapeamento de Hibernate e no banco de dados?
Y
YvGa
Da uma olhada na tag do hibernate.
P
pcalcado
emerleite:
[list]Após persistido, como eu recupero esse Endereco no banco se não tem um ID ? vou ter que comparar todos os campos na query ?[/list]
[list]Como Value Object teoricamente não tem ID, como na hora de persistir vai ficar registrado no BD que a Pessoa mora naquele Endereco?[/list]
[list]Vou ter que criar uma constraint no Banco com todos os campos para evitar duplicidade de Endereco ? Qual seria uma outra forma de garantir que não serão incluidos 2 Value ObjectsEndereco iguais?[/list]
[list]E no com hibernate como que fica pra recuperar e garantir que não serão incluidos 2 Value ObjectsEndereco iguais já que não tem ID ?[/list]
Acho que o problema aqui é de mapeamento objeto-relacional. Domain-Driven Design fala sobre como seus objetos são definidos, não sobre como representá-los em tabelas e bancos de dados. No seu caso específico se no modelo relacional o Value Object tem ou não ID não é um problema -diretamente- relacionado a modelagem de objetos, logo não é um aspecto de DDD.
B
BiraBoy
No caso do exemplo do Phillip no artigo da Mundo Java 17. A classe categoria no banco se torna um amontoado de colunas da tabela Cliente?
E
Emerson_Macedo
Correto, por isso o título da pergunta está relacionado a persistência do Value Object e não no seu conceito. Porém, parece que eu ainda não entendi alguma coisa …
Eu achava que um ID caracterizaria a Identidade o tornando uma Entity, mas devo ter entendido errado. Poderia me explicar onde estou fazendo a confusão toda ?
Abs …
A
Adriano_Almeida
Correto, por isso o título da pergunta está relacionado a persistência do Value Object e não no seu conceito. Porém, parece que eu ainda não entendi alguma coisa …
Eu achava que um ID caracterizaria a Identidade o tornando uma Entity, mas devo ter entendido errado. Poderia me explicar onde estou fazendo a confusão toda ?
Abs …
Cara não sei se você já chegou à um entendimento, mas a questão é a mistura que você está fazendo entre a persistência e o domínio. No seu domínio, o objeto XPTO vai ser um Value Object, porém, do ponto de vista da persistência, você vai precisar de um Id (considerando esse caso), mas note bem, o ID é necessário apenas do ponto de vista da persistência, não do ponto de vista do seu domínio, logo, para o seu domínio, ele não é um Entity.
S
sergiotaborda
pafuncio:
Cara não sei se você já chegou à um entendimento, mas a questão é a mistura que você está fazendo entre a persistência e o domínio. No seu domínio, o objeto XPTO vai ser um Value Object, porém, do ponto de vista da persistência, você vai precisar de um Id (considerando esse caso), mas note bem, o ID é necessário apenas do ponto de vista da persistência, não do ponto de vista do seu domínio, logo, para o seu domínio, ele não é um Entity.
Chamemos Key ao identificador de persistência. Pode ser um inteiro qq (ex : autonumber).
Chamemos ID à propriedade que traduz a Identidade da Entidade no sistema. Normalmente é composta de um ou mais vários campos de dados (ex. cpf).
Se existe um ID é porque é uma entidade.
VO significa que pode ser intercambiado entre duas entidades.
O exemplo do endereço.
Se E1 é o endereço da pessoa A e E2 é o endereço de B, se A e B têm no mesmo endereço então E1.equals(E2)
A e B não são ubiquos portanto têm 1 só endereço (OneToOne). Se eu fizer A.setAddress(B.getAddress())
estou dizendo que A têm agora o mesmo endereço de B.
Ao guardar no banco a tabela Pessoa tem:
a) os campos do endereço. Desta forma o objeto endereço é mapeado para campos da tabela pessoa. Isto representa implicitamente que o endereço é um VO de Pessoa
b) fazer o mesmo que (a) mas usando 2 tabelas. Pessoa tem um campo apontando o key do endereço
O endereço têm o key dele e uma foreign-key apontando pessoa (OneToOne).
Se o endereço não tiver uma foreign-key apontando pessoa será uma relação ManyToOne que viola o principio do VO. Não dá para reaproveitar o mesmo registro para E1 e E2 mesmo se eles são iguais ( se fossem entidades não so poderia como deveria).
Isto nos conduz a saber que A.setAddress() deve copiar o endereço de B para o seu e não apenas substituir a referencia.
classPessoasetAddress(Addressa){this.address.copyFrom(a);// isto porque o key de address não muda, só os dados}
Esta necessidade de usar a copia indica que o endereço com duas tabelas não é realmente um VO pois não é independente de quem o usa. (Se usar só a tabela pessoa, ñ tem problema nenhum). Ou seja, o E1 e o E2 não comutáveis. Logo, isto indica que o objeto endereço
pertence à pessoa com um vinculo muito maior. Isto faz pessoa não ser apenas uma entity, mas tb um agregado.
( ou seja, um grafo em que a raiz controla os outros nodos)
c) Aqui a tabela endereço não tem key e apenas uma foreign-key para pessoa.
Pessoa não tem key apontando endereço, mas tb não precisa. Esta forma é mais saudável e semelhante a (a) pois não obriga a fazer cópias. contudo esta opção de banco identifica um OneToMany e pode dar errado se não for bem implementado.
Uma pessoa não pode ter vários endereços, já que a pessoa não existem em vários lugares ao mesmo tempo.
O que a pessoa pode ter são vários endereços classificados por finalidade (moradia,entrega, faturamento, matriz, etc…)
Neste caso existe uma classificação da relação e o modelo terá que ser: uma pessoa tem vários EndereçosClassificados. Cada EndereçoClassificado tem um endereço e uma classificação.
L
Luca
Olá
Tópico muito bom. Só vou dar meu pitaco para reforçar o que o Sérgio escreveu de vários modos diferentes: CPF não é um identificador único.
A própria Receita Federal diz isto. Uma vez reclamei com a receita sobre um japonês safado que estava usado meu CPF de forma fraudulenta e a resposta da Receita foi de que no Brasil 30% (este foi o número dito pela auditora fiscal) dos CPFs estão errados ou são falsos. A maior parte dos erros está nos CPFs antigos em que o número era datilografado no cartão e o datilógrafo errava sem que o cidadão tivesse condições de suspeitar disto.
Portanto, nunca confiem apenas no número de CPF.
[]s
Luca
E
Emerson_Macedo
Sergio,
Obrigado pelos esclarecimentos, Eu realmente achei que a questão de ter um identificador do banco ia influenciar na minha classe tornando-a um Entity. Porém a sua explicação foi perfeita. Mais uma vez obrigado.
Luca,
Quanto ao CPF, eu concordo com o que você e o Sergio disseram. Acho que não me expressei direito.
O que eu quiz dizer é que em muitos sistemas vemos o CPF como o campo identificador de uma pessoa. Seria então errado uma classe Pessoa por exemplo com o atributo CPF sendo o seu ID em um determinado domínio que nada tem a ver com essas fraudes etc etc etc. Se não, o correto é ter um Número auto incremento para identificar essa Pessoa ? Nesse caso qual a melhor escolha para o ID desse Entity ?
Abs
A
Adriano_Almeida
emerleite:
Se não, o correto é ter um Número auto incremento para identificar essa Pessoa ? Nesse caso qual a melhor escolha para o ID desse Entity ?
Abs
Essa é uma boa pergunta. Nos Estados Unidos essa identificação é feita através do numero do seguro social.
Mas isso tambem depende do seu dominio, por exemplo, se voce vai modelar um sistema que Pessoa tambem pode ser uma crianca, CPF ja nao eh mais valido.
Em muitos dos domínios, um auto-incremento vale. Para alguns mais preciosistas, uma PK composta por CPF e um upperCase do nome. Não sei o que os mais experientes (Luca e Philip e demais) sugerem.
L
Luca
Olá
Para mim seria um campo ID incrementado dentro do sistema com a creta absoluta de que não há duplicidades.
E como eu disse, há CPFs duplicados por erro de digitação do cartão sem que haja fraude.
[]s
Luca
S
sergiotaborda
emerleite:
Nesse caso qual a melhor escolha para o ID desse Entity ?
Abs
A identidade da entidade é uma propriedade dela que pode ser manifestada no sistema como um VO da entidade.
Vc pode ter um VO EntityIdentity que deve obdecer o contrado de equals e hashCode e deve poder ser um identificador da entidade num Map. Isto significa que esse objeto tem que ser unico para cada entidade.
Em tese não importa a estrutura interna desse objeto desde que ele obdece ao contrado de equals/hashcode
Então vc pode ter um PersistenteKeyEntityIdentity que usa o key do registro ( um auto-number da vida) para ser o identificador. Vc pode ter um EntityFieldsEntityIdentity em que vc escolhe alguns campos da entidade para serem identificadores em conjunto (chave composta). Aqui vc pode usar o cpf o nome , ou qq coisa que vc quiser, já que fica encapculado no EntityIdentity. Vc pode usar o EntityIdentity para procurar pela entidade. exemplo
EntityIdentity id = PessoaEntityFieldsEntityIdentity.from (cpf, nome);
Pessoa p = manager.find(Pessoa.class,id);
Internamente o manager saberá como usar EntityIdentity para procurar por pessoa.
Mas tem um outro detalhe. Vc tem que assegurar que só existe uma pessoa para cada EntityIdentity.
Neste caso ao introduzir uma nova pessoa no sistema ele deveria testar isso. Para fazer isto o EntityIdentity não pode ser baseado no PersistenteKey já que esse numero sempre será diferente. Exemplo:
publicvoidstore(Pessoap){// p ainda não tem chae de persistenciaEntityIdentityid=PessoaEntityFieldsEntityIdentity.from(p);// verifica se existe uma pessoa com a mesma identidade// a pessoa sempre tem um identidadeif(manager.exists(id)){// se existe esta sendo tentada uma duplicaçãothrownewEntityDuplicationException();}// se não existe, guarda.manager.insert(p);// agora p tem chave de persistencia}
Existe portanto dois conceitos, a chave de persistência, que serve para controlar o estado e a referencia do objeto persistido e a chave de identidade que serve para identificar a entidade.