Duvida criação do dominio

Caros, estou com um problema e não sei como aplicar o DDD aqui.

Por exemplo, eu possuo um Produto, e esse produto recebe uma categoria, e essa categoria pertence a um tipo.

Exemplo:

Produto: Caneta
Categoria: Material de escritório
Tipo: Mateiral

No meu sistema eu tenho uma tela para cadastar minhas categorias e cada categoria possui um tipo. Entao na minha classe Categoria eu possuo uma propriedade tipoCategoria que é um objeto da classe TipoCategoria.

O tipo da categoria serve apenas para identificar o tipo da categoria, na tabela não há nenhum dado a nao ser seu id e nome. Minha duvida é se é realmente necessário criar esse objeto para guardar o Numero e o Nome da categoria.(acho que nao eh)

Isso ta me causando alguns problemas na hora de retornar dados do banco, por exemplo, quando a Categoria já existe que eu executo um find(), ele retorna essa categoria com o objeto TipoCategoria normalmente. Pois quando ele retorna os dados, ele pega o numero do TipoCategoria na tabela e cria automaticaemnte o objeto. Mas quando o objeto nao foi persistido na tabela, ele nao possui um id do tipo de categoria, e na hora que eu tento salvar, consequentemente nao salva o id na tabela.

Acho que to me enrolando com besteira, mas pra mim ta complicar aplicar DDD e me abstrar do banco de dados. Alguns objetos eu considero VO(DDD), mas nao consigo nao guardar id deles para persistencia(isso é errado?)

agradeço a ajuda!

Olá
Se um objeto é um VO, seu valor pode ser utilizado como chave primária do banco.
No seu caso, o tipo da categoria pode ser a chave da tabela.

Mas não se preocupe com banco agora. Desenvolva seu domínio primeiro e depois aplique a infra-estrutura nele. Utilize implementações dos seus Repositories que guardam os objetos em memória.

O que seria implementar a infraestrutura nele? Eu crio o meu dominio e adapto meus DAOs e Controllers para persistir e/ou retornar dados dos objetos?

Entenda como infra-estrutura tudo que está fora do domínio :smiley:
Exemplo: DAOs, controllers…

Mas eu acho que estou com um pouco de problema de interpretação. Tipo, se eu tiver um objeto TipoCategoria, eu só tenho guardado nele, o número dele(que no caso é o id dele na tabela) e o nome dele.

Quando eu vou salvar uma categoria, a unica coisa que me interessa do seu tipo, é o número e não o nome. Portanto eu acho que eu nao precisaria criar um objeto so para manipular o tipo da categoria, a categoria seria um dado como outro qualquer(o nome por exemplo).

Minha duvida é, estou certo?

Acho que você deve manter o objeto, mas como ele é um VO, você não precisa de um id porque o nome da categoria é tudo o que você precisa pra identificá-lo.
Se você mantiver o id, você poderá ter duas categorias iguais com ids diferentes.
Então ficaria algo assim:

[code]public class TipoCategoria {
private String tipoCategoria;

public TipoCategoria(String tipoCategoria) {
    this.tipoCategoria = tipoCategoria;
}

// Escreva apenas um get, pois VOs são imutáveis
public String getTipoCategoria() {
    return tipoCategoria;
}

}

// E na sua classe Produto…
public class Produto {
// …
private TipoCategoria tipoCategoria;
// …
}[/code]Abraços

Sim,é necessário

Isso está certo. Antes de persistir a categoria vc tem que associar um tipo a ela (categoria.setTipo(tipo)).
Assim não vai dar problema. O seu problema aqui é a incosistência do objeto categoria antes de ser persistido.
O tipo é um campo obrigatorio , logo deve ser preenchido antes de persistir.

Não ha problema guardar chaves para os objetos. Isso tem a ver com a necessidade de mapear objetos em tabelas.
O que destingue um VO de uma Entidade não é o facto de ter ou não uma chave. O que destingue é a identidade.


TipoCategoria t1 = new TipoCategoria ("Material");
TipoCategoria t2 = new TipoCategoria ("Material");

persist(t1)
persist(t2)

Se TipoCategoria é um VO então t1 e t2 são a mesma coisa representada duas vezes.
Num banco tudo tem que ter um chave, mas nem tudo tem um ID (identificador)
Um VO teria uma chave que é igual ao seu proprio valor. Ou seja, a tabela TipoCategoria teria apenas um campo “nome” e ele seria a chave. Teria chave, mas não teria ID. Mas por motivos práticos vc não faz isso.
Se a categoria A e B pertencem ao mesmo tipo, elas apenas teria o “nome” do tipo como uma das suas colunas.
O problema é que vc quer poder mudar esse nome indepedentemente das associações que já fez. Por isso vc cria uma coluna numérica e a usa como chave. Dessa forma vc pode mudar o texto, sem mudar o conceito.

A diferença entre um VO e uma Entidade no dominio é que quando vc fizer equals() o VO irá comparar o nome.
Se fosse uma entidade ele ira comparar o ID. Se vc erradamente cadastrar dois tipos de categoria com o mesmo nome eles terão id diferentes. Ai , vc , erradamente cadastra duas categorias , cada uma usando um registro diferente do tipo. Mas quando vc izer o teste A.getTipo().equals(B.getTipo()) o resultado será true (os nomes são iguais). Embora os tipos sejam registros diferentes as categorias pertencem ao mesmo tipo.

Se tipoCategoria fosse uma entidade aquele mesmo teste daria false ( os id são diferentes)

Hmmm… entendi, muito boa as explicações… só mais uma duvida… se o que me interessa em TipoCategoria é o nome para que eu possa manter uma integridade, não há problema nenhum esse VO guardar o id da tabela apenas para quando eu for persistir a Categoria eu tenha a informação da chave que esse Tipo representa na tabela não é?

[editado]
Ah e outra coisa… se eu quiser garantir que o usuário não cadastre nenhum tipo de categoria que já existe(considerando que a chave é o nome), há algum padrão que me ajude a fazer isso em meu dominio?

E se o nome é a chave, quando eu for fazer o update na tabela, ao invés de eu fazer “… where id_tipo_categoria = 1” eu vou fazer “… where nm_tipo_categoria = ‘Materiais’” ?

[quote=brunoviana]Hmmm… entendi, muito boa as explicações… só mais uma duvida… se o que me interessa em TipoCategoria é o nome para que eu possa manter uma integridade, não há problema nenhum esse VO guardar o id da tabela apenas para quando eu for persistir a Categoria eu tenha a informação da chave que esse Tipo representa na tabela não é?
[/quote]

sim. Vc usa TipoCategoria.id como chave no banco e a tabela Categoria tem um campo que aponta essa chave

não sei se é um padrão, mas vc cria uma query com os campos que forma a chave de unicidade.
depois faz um query com esses campos "traga todos os X cujos campos são iguais a Y’.
Ai, se algum for retonado é porque está tentando criar duplicados. Em opção pode usar os recursos do banco para marcar o campo como único (o que eu não gosto de fazer…).

[quote]
E se o nome é a chave, quando eu for fazer o update na tabela, ao invés de eu fazer “… where id_tipo_categoria = 1” eu vou fazer “… where nm_tipo_categoria = ‘Materiais’” ?[/quote]

Se vc se refere a encontar o TipoCategoria que conrresponde a um certo nome, sim.
Se vc se refere a encontrar a Categoria de um certo tipo, não. Vc usa o id. “… where categoria.tipo = tipocategoria.id