Minimizar problemas de uma modelagem bizarra

14 respostas
F

Olá !

Trabalho em uma empresa que está começando agora com desenvolvimento web.
Sou o único, na verdade, e cheguei a poucos meses.
Os outros são desenvolvedores desktop em outra linguagem e não sabem nada de OO.
Vamos lá…
Se vc tem varios tipos de usuarios (4 no meu caso) do sistema e cadastro pra cada um deles, é mais dq recomendado q cada um fique em uma tabela diferente.
E cada um seja um objeto no sistema com suas ações específicas.
Mas isso é muito dificil pra eles entenderem e querem uma tabela só com todos os tipos. :(:frowning:
Ou seja, 4 tipos de coisas em uma mesma tabela.
Tudo bem q muitos atributos desses 4 tipos serão iguais, mas vão ter campos q só serão preenchidos em alguns momentos.
Outros serão obrigatórios dependendo do tipo a ser cadastrado naquele momento.

Dessa forma, terei um objeto q pode ser de um dos 4 tipos.
Só saberei o tipo dele pelo perfil.
E terá relacionamento entre eles tb.

Pensei em “ligar o dane-se” e fazer exatamente como qrem e ficar tudo zoado.
Por outro lado penso oq posso fazer pra minimizar isso dentro do java em termos de objetos.
O que me aconselham a fazer ?

É triste qd vc qr fazer o melhor e não te deixam…
:cry:

14 Respostas

P

1º) Como vc vai tratar a parte de persistencia ??? JDBC ou algum ORM(hibernate, JPA) ???
2º) Lembre-se que não necessariamente a modelagem de classes(OO) tem que ser identica a modelagem do banco(Modelo Relacional)
3º) Vc usando algum ORM vc pode fazer as suas classes com tudo da OO e escolher uma das 3 formas de representar herança da OO
4º) Tbm é chato ver softs sendo desenvolvidos com linguagens OO mas a equipe ainda pensa na forma estruturada de desenvolvimento
5º) Mas tbm cuidado em querer usar o máximo da OO e se tornar um soft dificil de entender para os mais novos na linguagem e as vezes criando estrutura dentro de estruturas sem muito conteudo.

T

Boa tarde.

Não vejo problema do banco ter uma única tabela para todos os tipos de usuários.

O problema é deixar da mesma forma no modelo de classes. Na minha opinião o ideal mesmo é esse… uma tabela e várias classes, uma para cada tipo de usuário lógico existente, pois melhora muito o desempenho do sistema e mantém a separação lógica do modelo orientado a objeto.

Esta forma é inclusive apresentada na especificação JPA… que recomendo ser bem estudada antes de iniciar o uso de alguma implementação.

Espero ter ajudado…

F

Obrigado pelas respostas !

Eu estou usando spring, jpa e hibernate.

Eu pensei em fazer a modelagem de classes OO, mas eu não tenho experiência em dividir uma mesma tabela em objetos para busca ou inserção de dados.
Eu sei q dá, mas nunca precisei fazer isso antes pq sempre foi tudo modelado da melhor maneira possível.

Por isso ainda não sei fazer :oops:

T

Bom dia.

Apenas para polemizar um pouco…o que é modelar da melhor maneira possível? Se você se atentar a modelagem de banco utilizando as formas normais, o resultado vai ser de fato uma tabela.

A modelagem de uma tabela por classe não é de fato a melhor solução…faça alguns testes com jmeter com os dois modelos que você vai verificar a diferença gritante dos tempos de resposta da aplicação.

A meu ver banco relacional deve ser modelado como banco relacional e não como banco orientado a objeto. Cabe à camada DAO (e consequentemente aos mapeamentos das entidades) realizar as conversões necessárias. É um trabalho adicional para o desenvolvedor mas vale a pena. Para aplicações pequenas pode até não haver diferença grande nas estratégias de modelagem porém quando é necessário trabalhar com bancos de dados complexos e grandes (estou falando em 15 Teras…) essa diferença de estatégia pode causar bons e maus impactos na aplicação.

Meu trabalho de conclusão da pós graduação está sendo realizado inclusive com este foco. Se um dia eu concluir o trabalho publico algo sobre o assunto. De qualquer forma, melhor que meu trabalho é a especificação JPA. Lá você poderá encontrar todos os exemplos necessários para realizar cada estratégia de mapeamento.

Fico à disposição para auxiliar caso tenha algum problema no mapeamento.

Att,

F

Modelar da melhor maneira q digo é manter as tabelas organizadas e não tudo jogado em uma mesma tabela.
Um pouco de organização não faz mal a ninguém, fora que fica mais complexo o entendimento.
Pra ter uma ideia, nem o nome dessa tabela conseguimos definir.

Obrigado pela ajuda, qqr coisa posto aqui.

guilherme.dio

Só me diz uma coisa, essas 4 entidades que voce vai posusir no sistema serão diferenciadas somente por um perfil, correto ?

F

Não não… Se fosse só isso eu nem reclamava.
Terão muitos atributos iguais, mas tb terão atributos q só pertencem a cada uma delas.
Nesse caso não poderei usar Validation.
Fora q as ações no sistema tb são totalmente diferentes.

Mas tranquilo… Vou ver como faço pra mapear varios objetos para uma mesma tabela e criar os relacionamentos.

D

Comece lendo a especificação JPA.

douglaskd

e se fosse igual ao Active Directory:

Acesso(id_acesso,descricao,outros_dados)

Usuario(id_usuario,login,senha,outros dados)

Acesso_Usuario(id_usuario,id_acesso)

Usuario_Grupo(id_usuario,id_grupo)

Grupo(id_grupo,nome_grupo,descricao_grupo)

Acesso_Grupo(id_grupo,id_acesso)

Test-Drive:

Inserir Acesso('A-0050','Consulta Pedido Venda') //crio 3 Permissões
Inserir Acesso('A-0051','Cadastro Pedido Venda')
Inserir Acesso('A-0052','Exclui Pedido Venda')

Inserir Acesso('A-0001','Gerenciar Objetos e Acessos') //vou criar 1 separada para exemplificar

Inserir Grupo ('G-0088','Vendas','Acesso Padrão para Vendedores) //crio um grupo

Inserir Acesso_Grupo('G-0088','A-0050') //libero os 3 Acessos para todos os usuários do grupo
Inserir Acesso_Grupo('G-0088','A-0051')
Inserir Acesso_Grupo('G-0088','A-0052')

Inserir Usuario('U-0012','vendas','vendas') //crio usuário

Inserir Usuario_Grupo('U-0012','G-0088') //adiciono usuário ao grupo vendas

Inserir Acesso_Usuario('U-0012','A-0001') // libero o acesso somente a 1 usuário

e um método no java:

Boolean Validar_Acesso(String idUsuario, String idAcesso){

Boolean acessoPermitido;

// vai no banco e verifica se o usuário possúi acesso ou esta em um grupo que possúi acesso

return acessoPermitido

}
ai você utiliza esse método nas telas, nas criações dos menus etc

o que vocês acham ?

F
douglaskd:
e se fosse igual ao Active Directory:
Acesso(id_acesso,descricao,outros_dados)

Usuario(id_usuario,login,senha,outros dados)

Acesso_Usuario(id_usuario,id_acesso)

Usuario_Grupo(id_usuario,id_grupo)

Grupo(id_grupo,nome_grupo,descricao_grupo)

Acesso_Grupo(id_grupo,id_acesso)

Test-Drive:

Inserir Acesso('A-0050','Consulta Pedido Venda') //crio 3 Permissões
Inserir Acesso('A-0051','Cadastro Pedido Venda')
Inserir Acesso('A-0052','Exclui Pedido Venda')

Inserir Acesso('A-0001','Gerenciar Objetos e Acessos') //vou criar 1 separada para exemplificar

Inserir Grupo ('G-0088','Vendas','Acesso Padrão para Vendedores) //crio um grupo

Inserir Acesso_Grupo('G-0088','A-0050') //libero os 3 Acessos para todos os usuários do grupo
Inserir Acesso_Grupo('G-0088','A-0051')
Inserir Acesso_Grupo('G-0088','A-0052')

Inserir Usuario('U-0012','vendas','vendas') //crio usuário

Inserir Usuario_Grupo('U-0012','G-0088') //adiciono usuário ao grupo vendas

Inserir Acesso_Usuario('U-0012','A-0001') // libero o acesso somente a 1 usuário

e um método no java:

Boolean Validar_Acesso(String idUsuario, String idAcesso){

Boolean acessoPermitido;

// vai no banco e verifica se o usuário possúi acesso ou esta em um grupo que possúi acesso

return acessoPermitido

}
ai você utiliza esse método nas telas, nas criações dos menus etc

o que vocês acham ?

Oq é isso cara ?? kkkkkkkkkkk

Pessoal, preciso de uma ajuda com mapeamento.

Tenho aquela tabela q guarda monte de coisas.
Ela guarda gerentes e corretores, além de outras coisas. :oops:

O negócio é, como digo pro jpa q um gerente tem varios corretores, já q a tabela é a mesma e ele precisa buscar em um outro atributo q não seja a chave primaria ?

Vejam oq tenho:

USUARIO (gerente ou corretor, nesse exemplo)
-----------
id
id_gerente (só se o perfil for corretor, será usado para dizer qual gerente de um corretor)
perfil
etc..

Na minha classe tenho:

// um gerente possui varios corretores
@OneToMany
private List corretores;

Mas eu preciso dizer pro jpa q ele deve usar o id_gerente, neste caso.

Como faço isso ?

Ps: depois q aprender dessa forma irei dividir os objetos e fazer de outra

Edit:

Normalmente uso o mappedBy pra apontar pra atributo em outra classe..
Vou testar na mesma pra ver oq acontece..

gomesrod

Eu não estava vendo nada de errado em ter uma única tabela, porque achei que esses tipos de usuário eram mais uma questão de perfil. Mas agora com esse último post que traz mais detalhes fiquei em dúvida.

Uma pergunta que deve ser respondida antes de tudo é:
-> Será que os Gerentes, Corretores, etc são simplesmente tipos de usuário? Ou na verdade são entidades próprias dentro do modelo ?

Essa resposta é meio abstrata… ser um “gerente” significa apenas ter permissão para fazer as transações X e Y, ou ele tem seu próprio papel dentro do modelo, com seus próprios relacionamentos e participação diferenciada nas operações de negócio ?

Caso vocês cheguem à conclusão que cada um desses papéis (ou pelo menos alguns deles) são na verdade entidades, então não faz mesmo sentido estarem na mesma tabela.

F

gomesrod:
Eu não estava vendo nada de errado em ter uma única tabela, porque achei que esses tipos de usuário eram mais uma questão de perfil. Mas agora com esse último post que traz mais detalhes fiquei em dúvida.

Uma pergunta que deve ser respondida antes de tudo é:
-> Será que os Gerentes, Corretores, etc são simplesmente tipos de usuário? Ou na verdade são entidades próprias dentro do modelo ?

Essa resposta é meio abstrata… ser um “gerente” significa apenas ter permissão para fazer as transações X e Y, ou ele tem seu próprio papel dentro do modelo, com seus próprios relacionamentos e participação diferenciada nas operações de negócio ?

Caso vocês cheguem à conclusão que cada um desses papéis (ou pelo menos alguns deles) são na verdade entidades, então não faz mesmo sentido estarem na mesma tabela.

É assim…
São 5 perfis no total: adm, diretor, gerente, corretor e cliente
Cada um deles tem um papel no sistema, mas oq mais terá é apenas consulta de clientes e contratos dos clientes.

Oq ELES fizeram:

Tabela Usuario terá: adm, diretor, gerente e corretor
Tabela Cliente terá: cliente

Só q nessa tabela de Usuario tb tem o login, senha e perfil de cada um.
O cliente tb deve ser um usuário, então preciso de um relacionamento com essa tabela.

Entre Usuario e Cliente tenho 3 relacionamentos.
1 - para o cliente ter login, senha e perfil
2 - um cliente tem um gerente
3 - um cliente tem corretor

Na tabela de Usuario eu tenho o auto relacionamento, pq um corretor pertence a um cliente.

Não me xinguem ! Não sou o pai desse monstrinho…
Parece q fizeram só pra complicar mesmo.

fantomas

fdiaz2011:
// um gerente possui varios corretores
@OneToMany
private List corretores;

Mas eu preciso dizer pro jpa q ele deve usar o id_gerente, neste caso.

Como faço isso ?

@@OneToMany(fetch = FetchType.LAZY, optional = true) @JoinColumn(name = "ID_GERENTE", nullable = true, insertable = true, updatable = true) private List<Usuario> corretores;

Faz um teste para ver se funciona deste jeito.

flws

F

fantomas:
fdiaz2011:
// um gerente possui varios corretores
@OneToMany
private List corretores;

Mas eu preciso dizer pro jpa q ele deve usar o id_gerente, neste caso.

Como faço isso ?

@@OneToMany(fetch = FetchType.LAZY, optional = true) @JoinColumn(name = "ID_GERENTE", nullable = true, insertable = true, updatable = true) private List<Usuario> corretores;

Faz um teste para ver se funciona deste jeito.

flws

Funcionou sim amigão !
Só tive q tirar o optional = true, q não pode ter ali

Obrigado !! :stuck_out_tongue:

Criado 7 de novembro de 2012
Ultima resposta 9 de nov. de 2012
Respostas 14
Participantes 8