| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 08/10/2009 15:18:06
|
barenko
JavaBaby
![[Avatar]](/images/avatar/4c32ad344b09ff872f942b6d2196e720.jpg)
Membro desde: 07/04/2008 21:09:30
Mensagens: 81
Offline
|
Olá pessoal! Estou com um conflito entre a inicialização do objeto e a inicialização reflexiva de atributos final.
É o seguinte:
Estou fazendo uma espécie de DAO voltado para programadores oracle, ou seja: ele terá uma sintaxe bem similar à DML. Para conseguir a flexibilidade necessária para gerar selects complexos, precisei criar um Pojo inteligente (DbTable) que se encarrega de carregar toda a infraestrutura de mapeamento com as tabelas do banco. Os "Beans" serão filhos da DbTable e terão que declarar suas colunas como objetos TableColumn anotados.
Para assegurar que os selects desse DAO sejam feitos de forma muito similar à da DML, fiz que esses atributos fossem publicos e finais. Nota: esses atributos representam colunas e naõ dados.
Devido aos atributos de coluna serem publicos, eu os tornei final p/ evitar problemas. Porém ao fazer isso, o java me obriga a inicializar a variável (sendo assim, atribuo null nela).
O problema aparece quando vou inicializar meu "Bean". Pela pilha de inicialização, o java chama o super do construtor (DbTable) que é encarregado de instanciar os atributos TableColumn da classe filha via reflexão. Porém ao executar o construtor da classe (Client), essa anula o TableColumn instanciado pela DbTable!
Seguem abaixo os códigos que exemplificam meu problema (Eu simplifiquei ao máximo as classes apenas para evidenciar o problema em si).
Saída:
Inicio de DbTable()...
DbTable() Instanciou o atributo id com [TableColumn@1c184f4]
Clients() Instanciou o atributo id com [null]
ID após o termino da inicialização: null
Não consegui descobrir como modificar um atributo para final via reflexão, se alguém souber como fazer, seria muito útil.
Transformar os objetos TableColumn em static também naõ ajudará, pois isso causará problemas para referenciar as colunas do select com as tabelas envolvidas.
Alguém poderia me ajudar? Até com idéias mirabolantes de magia negra?
This message was edited 1 time. Last update was at 08/10/2009 15:19:48
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 08/10/2009 16:02:44
|
palmadias
JavaTeenager
Membro desde: 08/07/2008 07:41:08
Mensagens: 192
Localização: São Paulo/SP
Offline
|
Vc já pensou em usar JPA?
Parece que vc tá reinventando a roda.
|
http://palmadias.blogspot.com/ |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 08/10/2009 16:21:13
|
barenko
JavaBaby
![[Avatar]](/images/avatar/4c32ad344b09ff872f942b6d2196e720.jpg)
Membro desde: 07/04/2008 21:09:30
Mensagens: 81
Offline
|
Olá!
Já pensei em JPA sim, só q encontrei alguns problemas nessa abordagem... talvez por inexperiência minha no assunto...
Por exemplo:
Tenho meu genericDao com beans anotados. Se quero os nomes dos clientes de RG X, Y e Z, faço 3 pesquisas (queryBySample) criando um Bean e setando o RG para cada um dos valores e recebo 3 beans que possuem todos os atributos do bean populados.
Em outras palavras:
O q deveria ser isso:
select name from clients where rg in(X,Y,Z)
Se transforma nisso:
select id, name, address, age, is_active, ......, created_at from clients where rg = X
select id, name, address, age, is_active, ......, created_at from clients where rg = Y
select id, name, address, age, is_active, ......, created_at from clients where rg = Z
3 requisições de todos os campos ao banco de dado. Em tabelas pequenas, tudo bem. Mas e para sistemas que possuem tabelas de 150 campos? E se o desempenho for critico? Entende a origem do meu problema?
Minha idéia é criar algo assim:
Client client = new Client();
select(client.name).from(client).where(client.rg.in(X,Y,Z))
E com isso, o meu framework montaria um único select e retornaria os objetos que eu preciso manipular.
Claro, se já existir algo capaz de fazer isso disponível, eu tratarei de ver na mesma hora!
This message was edited 2 times. Last update was at 08/10/2009 16:22:52
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 09/10/2009 13:39:14
|
barenko
JavaBaby
![[Avatar]](/images/avatar/4c32ad344b09ff872f942b6d2196e720.jpg)
Membro desde: 07/04/2008 21:09:30
Mensagens: 81
Offline
|
E ai, ninguém tem nenhuma idéia p/ tentar driblar o problema?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 14/10/2009 08:53:36
|
Marky.Vasconcelos
Moderador
![[Avatar]](/images/avatar/04940fadf3702cbd84b7a48161037c4f.png)
Membro desde: 11/04/2007 18:18:20
Mensagens: 5932
Localização: São Paulo/SP
Offline
|
Eu acho que hibernate ainda te resolve isso.
|
Facebook @MarkyHitchhiker +Mark WP: MarkyTech's
Projects:
Android Roadmap - Aprenda Android do inicio (Java é o unico pre-requisito)
Towel ( ObjectTableModel & Swing & Utils )
Tower Defense Game - Java2D [Open-Source] [How-to-play]
EVGD: Programação de jogos (links) Ponto V! - Desenvolvimento de jogos para indies, curiosos e profissionais
DefaultTableModel?! PARE! Não faça isso! Faça melhor!
Dicas: Faça perguntas inteligentes! ; MigLayout ; GridBagLayout (Joke)
Develop games is fantastic, with words you can make worlds!!!
DON'T PANIC!
MarkyHitchhiker's Blog! |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 14/10/2009 09:50:30
|
Lavieri
GUJ Master
![[Avatar]](/images/avatar/7b41bfa5085806dfa24b8c9de0ce567f.png)
Membro desde: 27/01/2004 13:39:31
Mensagens: 1851
Localização: João Pessoa / PB
Offline
|
resolve mesmo
na verdade da pra fazer melhor com hibernate
com JPA tambem da pra fazer
JPA QL = "c From Client as c where c.rg in(X,Y,Z)";
se vc só quer o nome = "c.name From Client as c where c.rg in(X,Y,Z)";
não tente reiventar a roda, que da muitaaaaaaaa dor de cabeça ^^ .... pessoal do hibernate ta nessa a nos já
This message was edited 1 time. Last update was at 14/10/2009 09:53:04
|
Sun Certified Java Programmer (SCJP 6)
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
Meu blog -> http://blog.tomazlavieri.com.br/ |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 14/10/2009 22:07:57
|
barenko
JavaBaby
![[Avatar]](/images/avatar/4c32ad344b09ff872f942b6d2196e720.jpg)
Membro desde: 07/04/2008 21:09:30
Mensagens: 81
Offline
|
Interessante, essas dicas resolvem mesmo o problema da clausula "IN". Muito bom!
Só faltam alguns outros problemas, vou listar aqui para vcs verem:
Trazer apenas algumas colunas da tabela ao invez da linha toda - Tem lugares q eu só preciso de 2 ou 3 campos e não de 150... e cá entre nós, fazer um beam p/ representar cada "visão" da mesma tabela (assim traria apenas as colunas q estao no bean) é algo um tanto qto estúpido e sujo p/ se fazer num código... eu vejo isso como retrabalho desnecessário, aumento potencial de pontos de bug e dificuldade no entendimento posterior
Caso eu queira fazer um count ou chamar alguma outra função de banco na lista de colunas do select - O q eu vi até agora é q isso deve ser feito por fora, no melhor estilo RAW JDBC
Fazer agrupamentos "group by" ou "having by" com componentes nativos - novamente sem recorer ao velho RAW JDBC
Criar joins com tabelas diferentes e obter algo como uma lista dos objetos utilizados no select - Por ex: se eu fizer um join para obter 2 colunas de cliente e 2 colunas de produto, eu receberia 2 objetos por linha retornada contendo os dados das minhas colunas
Além disso eu tenho fortes limitações cerebrais e motoras que me bloqueiam sempre que eu vejo que o select que eu quero executar possui apenas 15 singelas linhas bem identadas e de fácil entendimento se transformam em um monstro amorfo de cerca de 30 linhas. - Claro q exagerei, na maioria dos casos normais de tabela<->bean isso não ocorre. Esses problemas costumam aparecer em relatórios e aplicações de análise, que precisam cruzar dados das mais diferentes formas
Eu não quero provocar guerra ou discussões fervorozas em defesa do hibernate, JPA ou sei lá o q. Apenas estou espondo os problemas que já presenciei qdo decidi me aventurar pelos mares do hibernate e da JPA.
Por isso decidi fazer um framework de persistência voltado à programação de scripts (mesma utilizada pelos bancos de dados relacionais padrões de mercado) ao invés de fazê-lo voltado à programação orientada a objetos.
Aliás, q mal há em criar uma roda com câmara e pneu quando tudo que se tem são rodas de madeira e metal?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/10/2009 11:13:35
|
Marky.Vasconcelos
Moderador
![[Avatar]](/images/avatar/04940fadf3702cbd84b7a48161037c4f.png)
Membro desde: 11/04/2007 18:18:20
Mensagens: 5932
Localização: São Paulo/SP
Offline
|
barenko wrote:Interessante, essas dicas resolvem mesmo o problema da clausula "IN". Muito bom!
Só faltam alguns outros problemas, vou listar aqui para vcs verem:
Trazer apenas algumas colunas da tabela ao invez da linha toda - Tem lugares q eu só preciso de 2 ou 3 campos e não de 150... e cá entre nós, fazer um beam p/ representar cada "visão" da mesma tabela (assim traria apenas as colunas q estao no bean) é algo um tanto qto estúpido e sujo p/ se fazer num código... eu vejo isso como retrabalho desnecessário, aumento potencial de pontos de bug e dificuldade no entendimento posterior
O Hibernate tem o esquema de apenas carregar o dado do atributo quando voce fizer um getAlgo no objeto. Então acho que mesmo usando duas colunas voce pode carregar o objeto inteiro sem se preocupar.
PS: Claro se voce não mudar essa função para o modo EAGER ou então não pegar da Session com o comando get(Seriable id)
barenko wrote:
Caso eu queira fazer um count ou chamar alguma outra função de banco na lista de colunas do select - O q eu vi até agora é q isso deve ser feito por fora, no melhor estilo RAW JDBC
Quanto a do group by e havin by e a outra questão não sei te responder.
|
Facebook @MarkyHitchhiker +Mark WP: MarkyTech's
Projects:
Android Roadmap - Aprenda Android do inicio (Java é o unico pre-requisito)
Towel ( ObjectTableModel & Swing & Utils )
Tower Defense Game - Java2D [Open-Source] [How-to-play]
EVGD: Programação de jogos (links) Ponto V! - Desenvolvimento de jogos para indies, curiosos e profissionais
DefaultTableModel?! PARE! Não faça isso! Faça melhor!
Dicas: Faça perguntas inteligentes! ; MigLayout ; GridBagLayout (Joke)
Develop games is fantastic, with words you can make worlds!!!
DON'T PANIC!
MarkyHitchhiker's Blog! |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/10/2009 12:02:55
|
barenko
JavaBaby
![[Avatar]](/images/avatar/4c32ad344b09ff872f942b6d2196e720.jpg)
Membro desde: 07/04/2008 21:09:30
Mensagens: 81
Offline
|
Mark_Ameba wrote:
O Hibernate tem o esquema de apenas carregar o dado do atributo quando voce fizer um getAlgo no objeto. Então acho que mesmo usando duas colunas voce pode carregar o objeto inteiro sem se preocupar.
PS: Claro se voce não mudar essa função para o modo EAGER ou então não pegar da Session com o comando get(Seriable id)
Fiquei curioso qto a como funciona isso...
Por ex:
Eu tenho um bean (B) com 3 atributos (a1, a2, a3).
Configuro o Hibernate para Fetch.SELECT (ou o LAZY depreciado).
Até ai, ok... a partir de agora, corrija-me se eu estiver errado:
Eu quero obter apenas o a1. Ao efetuar um select com o hibernate, eu passo o bean e ele faz um equivalente à:
Pode ser que o hibernate não carregue as colunas no bean (para otimizar desempenho), mas os valores estarão em seu cache interno. Se eu precisar do conteúdo do a1 fazendo algo como :
O hibernate usará o mock que ele me retornou para obter o valor do campo a1 que estava no cache. Não é isso?
Se for isso, utilizar ou não Lazy implicará no mesmo problema: trazer tudo da linha do banco no select...
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/10/2009 15:05:59
|
Marky.Vasconcelos
Moderador
![[Avatar]](/images/avatar/04940fadf3702cbd84b7a48161037c4f.png)
Membro desde: 11/04/2007 18:18:20
Mensagens: 5932
Localização: São Paulo/SP
Offline
|
Se voce fazer o getClass do objeto do Hibernate (Que provavelmente é encapsulado como um seu) voce vai ser que este extends o seu.
O hibernate cria novas classes em execução e nos getters ele coloca código para quando for acessado o atributo ele faça o select no banco.
|
Facebook @MarkyHitchhiker +Mark WP: MarkyTech's
Projects:
Android Roadmap - Aprenda Android do inicio (Java é o unico pre-requisito)
Towel ( ObjectTableModel & Swing & Utils )
Tower Defense Game - Java2D [Open-Source] [How-to-play]
EVGD: Programação de jogos (links) Ponto V! - Desenvolvimento de jogos para indies, curiosos e profissionais
DefaultTableModel?! PARE! Não faça isso! Faça melhor!
Dicas: Faça perguntas inteligentes! ; MigLayout ; GridBagLayout (Joke)
Develop games is fantastic, with words you can make worlds!!!
DON'T PANIC!
MarkyHitchhiker's Blog! |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/10/2009 08:52:56
|
barenko
JavaBaby
![[Avatar]](/images/avatar/4c32ad344b09ff872f942b6d2196e720.jpg)
Membro desde: 07/04/2008 21:09:30
Mensagens: 81
Offline
|
Mark_Ameba wrote:O hibernate cria novas classes em execução e nos getters ele coloca código para quando for acessado o atributo ele faça o select no banco.
Vou ver se eu entendi:
Bean: B
Atributos b1, b2, b3,... bn
Mark_Ameba 'levemente modificado wrote:
Isso deve recuperar o objeto com b3 = X.
Por trás o hibernate faz o q? um select p/ recuperar apenas os ids?
Blz, se for isso, vai ficar bem rápido para obter as referências reais dos objetos (id's)
Ai, vc disse q o hibernate faria um select por atributo. Então se eu fizer isso:
O hibernate, por trás, fará isso?
Então, se eu fizer isso:
O hibernate fará isso?
Deduzi isso pensando na pilha de chamadas do java. Em lazy é isso mesmo q ocorre?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/10/2009 09:04:20
|
Lavieri
GUJ Master
![[Avatar]](/images/avatar/7b41bfa5085806dfa24b8c9de0ce567f.png)
Membro desde: 27/01/2004 13:39:31
Mensagens: 1851
Localização: João Pessoa / PB
Offline
|
vc pode escolher que campos trazer no hibernate, mais isso vai te custar ter q popular o objeto java, o que é uma chatisse...
objetos com 150 atributos são uma bizzarrice do ponto de vista OO, não importa se na tua tabela tem 150 atributos, em Java, vc pode modelar para ser varios objetos com varios atributos...
é possivel ainda agrupos N atributos de uma mesma tabela em objetos @Embedabble, esses objetos funciona mais ou menos assim: e neste caso tornas esses embeddable groups lazy
mesmo assim é possivel separar uma mesma tabela em N objetos java, com relacionamentos 1-1, para não puxar a linha toda de uma vez
This message was edited 1 time. Last update was at 16/10/2009 09:05:51
|
Sun Certified Java Programmer (SCJP 6)
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
Meu blog -> http://blog.tomazlavieri.com.br/ |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/10/2009 09:06:07
|
Mauricio Linhares
Moderador
![[Avatar]](/images/avatar/97af07a14cacba681feacf3012730892.jpg)
Membro desde: 09/01/2005 23:28:22
Mensagens: 3717
Localização: João Pessoa, Paraíba - Brasil
Offline
|
Não, não é isso que acontece, o Hibernate não deixa você selecionar os campos que ele vai trazer, ele sempre vai buscar todas as colunas, o que pode ser lazy loaded são as associações.
Usando hibernate você faria assim - http://docs.jboss.org/hibernate/stable/core/reference/en/html/querysql.html#d0e13696
Mas tabelas com 150 colunas são um lindo sinal de que o banco de dados está com sérios problemas
|
Meu blog sobre desenvolvimento | My Last.fm | @mauriciojr
Screencast de Introdução a linguagem Objective-C |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/10/2009 09:09:04
|
Lavieri
GUJ Master
![[Avatar]](/images/avatar/7b41bfa5085806dfa24b8c9de0ce567f.png)
Membro desde: 27/01/2004 13:39:31
Mensagens: 1851
Localização: João Pessoa / PB
Offline
|
Mauricio Linhares wrote:Mas tabelas com 150 colunas são um lindo sinal de que o banco de dados está com sérios problemas 
quote++
agree
|
Sun Certified Java Programmer (SCJP 6)
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
Meu blog -> http://blog.tomazlavieri.com.br/ |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/10/2009 09:21:10
|
Marky.Vasconcelos
Moderador
![[Avatar]](/images/avatar/04940fadf3702cbd84b7a48161037c4f.png)
Membro desde: 11/04/2007 18:18:20
Mensagens: 5932
Localização: São Paulo/SP
Offline
|
É algo parecido com isso mesmo.
Mas o comando get da Session já retorna com o select completo, para ter esse efeito voce precisa carregar com o load.
Pra voce ver.
No hibernate.properties coloque a opção para mostrar o SQL
acho que é hibernate.show_sql=true da uma pesquisada.
Depois faça um código como abaixo e rode pra ver como isso funciona.
|
Facebook @MarkyHitchhiker +Mark WP: MarkyTech's
Projects:
Android Roadmap - Aprenda Android do inicio (Java é o unico pre-requisito)
Towel ( ObjectTableModel & Swing & Utils )
Tower Defense Game - Java2D [Open-Source] [How-to-play]
EVGD: Programação de jogos (links) Ponto V! - Desenvolvimento de jogos para indies, curiosos e profissionais
DefaultTableModel?! PARE! Não faça isso! Faça melhor!
Dicas: Faça perguntas inteligentes! ; MigLayout ; GridBagLayout (Joke)
Develop games is fantastic, with words you can make worlds!!!
DON'T PANIC!
MarkyHitchhiker's Blog! |
|
|
 |
|
|