| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 13/07/2010 22:44:52
|
brunoskrebs
JavaBaby
Membro desde: 01/09/2004 15:25:57
Mensagens: 75
Offline
|
Boa noite,
eu tenho uma classe que contém uma propriedade que é um list de enums.
Onde Perfil é um enum.
Agora para tornar a query mais performatica eu estou tentando fazer a query com um left join para que o JPA já traga os usuários já com a associação preenchida, mas não estou conseguindo.
Eu tentei dessa forma:
e também dessa:
Porém a primeira retornou usuários repetidos (se o usuário tem 2 perfis ele aparecia 2 vezes, se tem 3 aparece 3 vezes no resultado e assim por diante).
E a segunda query não retornou nenhum resultado
Alguém sabe como realizar essa consulta?
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 13/07/2010 23:17:55
|
jakefrog
GUJ Expert
![[Avatar]](/images/avatar/6e2400ec18b6f1952f1053c65df7a8b6.png)
Membro desde: 22/01/2007 22:00:53
Mensagens: 4181
Offline
|
Bem, não parei para analisar a query pq iria ter que ver a estrutura das tabelas. Mas vc pode trocar de List<> para Set<> .
Ele vai eliminar os objetos repetidos.
Apenas se lembre de criar hashCode() e equals() na sua classe.
=D
|
Meu blog sobre java uaiHebert.com
Conceitos OO - Diga, não pergunte!, Lei de Demeter
TDD Primeiros Passos, JUnit com HSQLDB, JPA e Hibernate, Cobertura de testes com JUnit Ant e Emma, Cobrindo seus testes com Cobertura, JUnit, HSQLDB, JPA
Código Limpo: Partes: 01,02,03,04,05
Web/JSF - Criando um WebServer, Tratando Exceções, Autenticação de Usuários (Filter/Servlet), JSF - Hello World, AutoComplete, JSF: Converter e Bean Auto Complete, Validação de Login de Usuário com JSF e JAAS, JSF Exibindo Objeto e Mensagens após Redirect, JSF Exemplos Simples com Ajax, JSF Parametros por Get Request RESTFullAplicação Web Completa JSF EJB JPA JAAS, Lazy JSF Datatable Pagination (Primefaces)
Design Pattern - Strategy, Design Pattern - Observer (Parte 01), Design Pattern - Observer (Parte 02)
Business (JPA)- Hibernate 3 com JPA 2, Create schema script: Ant, Hibernate 3 e JPA 2, TableGenerator Chave Primária Simples, SequenceGenerator,Chave Primária Composta, Mapeando Datas (Date) e Enum, Mapeando Duas Tabelas em uma Classe, @OneToOne Unidirecional e Bidirecional, @OneToMany e @ManyToOne Unidirecional e Bidirecional, @ManyToMany Unidirecional e Bidirecional, Ordernando listas e utilizando Map como atributo mapeado,Uma tabela por herança, JPA Uma Classe por Sub-Classe, JPA Consultas e Dicas, [HOT]Quatro soluções para LazyInitializationException[HOT]
SCJP(1.6 - Ingles - 29/12/2009)
SCWCD(1.5 - Ingles - 30/06/2010)
Vamos em frente que atrás vem gente! |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 14/07/2010 00:32:49
|
brunoskrebs
JavaBaby
Membro desde: 01/09/2004 15:25:57
Mensagens: 75
Offline
|
obrigado pela resposta, porém não é a solução. o problema não está em ter perfis repetidos para um usuário e sim no fato de as duas consultas que eu apresentei não estarem retornado o esperado.
e o esperado no caso era um usuário com seus devidos perfis.
eu consigo isso com
e depois acessando os perfis através de u.getPerfis(). Porém isso resulta em mais acessos ao banco para retornar os perfis de cada usuário que eu listo, e isso no caso se torna muito oneroso.
e por fim, para analisar a query nao teria que analisar estrutura das tabelas levando em conta que eu uso jpql (sql orientado a objetos). mas de qualquer forma segue a minha classe Usuário com a sua associação com o enum Perfil:
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 14/07/2010 15:14:53
|
breno500as
Virtual Machine Man
Membro desde: 11/10/2007 17:53:07
Mensagens: 614
Localização: Belo Horizonte - MG
Offline
|
Fazendo isso:
Ou fazendo isso:
Não vejo muito ganho de performance não....
Você pode procurar por outras alternativas como marcar relacionamentos como LAZY ou ao invés de utilizar from (onde todo o grafo do objeto é recuperado) utilizar um construtor na query (select new)...
|
Sun Certified Java Programmer 5.0
Sun Certified Web Component Developer 5.0
Sun Certified Business Component Developer 5.0 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 14/07/2010 17:28:42
|
derlon
JavaTeenager
Membro desde: 12/12/2009 14:07:01
Mensagens: 150
Offline
|
brunoskrebs wrote:..
E a segunda query não retornou nenhum resultado
..
@brunoskrebs,
Vc não nos informou q BD vc usa. Ah, e pq q vc num coloca -> 'showSql=true'??!
Se for Oracle, p/ex., ele exige q todos os Campos q estejam no GroupBy tem q estar no Select, tb sacou??!
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 15/07/2010 17:24:22
|
brunoskrebs
JavaBaby
Membro desde: 01/09/2004 15:25:57
Mensagens: 75
Offline
|
Acredito que não seja esse o problema considerando que no JPQL "select u from Usuario u" corresponde a "select * from usuario". Mas sim eu uso Oracle.
E sobre o ganho de performance, eu prefiro que o meu aplicativo faça apenas 1 consulta no banco de dados que retorne os usuários já com seus devidos perfis do que faça 1 + n consultas para retornar os perfis. Imaginem se eu listo seila 50 usuários, são 51 consultas contra 1 consulta possível...
Eu vou fazer mais algumas tentativas num futuro bem próximo, no momento estou fazendo um outro requisito. Mas se eu obtiver sucesso posto a forma aqui.
Valeu!
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/07/2010 00:52:23
|
jakefrog
GUJ Expert
![[Avatar]](/images/avatar/6e2400ec18b6f1952f1053c65df7a8b6.png)
Membro desde: 22/01/2007 22:00:53
Mensagens: 4181
Offline
|
Vc pode tentar usar então o lazy load. Por default é false, se vc setar true, ele vai buscar todo mundo. Eu sei que tem como usar com o hibernate, não sei para JDBC ou outras camadas de acesso a banco.
O lazy load tem seu conceito de "Não carregue se não precisar", por isso seu valor default é false. No caso, quando vc colocar true, para os perfis, ele vai carregar todo mundo.
Dá uma olhada para adaptar isso ao seu projeto. Nesse caso ele irá trazer toda sua lista de perfis quando vc buscar pelos usuários! [=
|
Meu blog sobre java uaiHebert.com
Conceitos OO - Diga, não pergunte!, Lei de Demeter
TDD Primeiros Passos, JUnit com HSQLDB, JPA e Hibernate, Cobertura de testes com JUnit Ant e Emma, Cobrindo seus testes com Cobertura, JUnit, HSQLDB, JPA
Código Limpo: Partes: 01,02,03,04,05
Web/JSF - Criando um WebServer, Tratando Exceções, Autenticação de Usuários (Filter/Servlet), JSF - Hello World, AutoComplete, JSF: Converter e Bean Auto Complete, Validação de Login de Usuário com JSF e JAAS, JSF Exibindo Objeto e Mensagens após Redirect, JSF Exemplos Simples com Ajax, JSF Parametros por Get Request RESTFullAplicação Web Completa JSF EJB JPA JAAS, Lazy JSF Datatable Pagination (Primefaces)
Design Pattern - Strategy, Design Pattern - Observer (Parte 01), Design Pattern - Observer (Parte 02)
Business (JPA)- Hibernate 3 com JPA 2, Create schema script: Ant, Hibernate 3 e JPA 2, TableGenerator Chave Primária Simples, SequenceGenerator,Chave Primária Composta, Mapeando Datas (Date) e Enum, Mapeando Duas Tabelas em uma Classe, @OneToOne Unidirecional e Bidirecional, @OneToMany e @ManyToOne Unidirecional e Bidirecional, @ManyToMany Unidirecional e Bidirecional, Ordernando listas e utilizando Map como atributo mapeado,Uma tabela por herança, JPA Uma Classe por Sub-Classe, JPA Consultas e Dicas, [HOT]Quatro soluções para LazyInitializationException[HOT]
SCJP(1.6 - Ingles - 29/12/2009)
SCWCD(1.5 - Ingles - 30/06/2010)
Vamos em frente que atrás vem gente! |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/07/2010 10:52:52
|
brunoskrebs
JavaBaby
Membro desde: 01/09/2004 15:25:57
Mensagens: 75
Offline
|
jakefrog, eu sei sobre o lazy loading, na verdade setar o fetch type dessa associação não irá me adiantar, pois:
1 - todas as vezes que eu carregar um usuário ele já vai carregar os perfis. e eu não quero isso, quero que a minha consulta especifica para trazer usuários com perfis faça isso, com um só select ao banco de dados.
2 - o fetchtype eager não vai fazer com que apenas um select traga os usuários com seus devidos perfis.
e sobre usar lazy load, isso não funciona assim no jdbc pois no jdbc tu faz essas associações, e cria os objetos "na mão"...
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/07/2010 23:21:05
|
brunoskrebs
JavaBaby
Membro desde: 01/09/2004 15:25:57
Mensagens: 75
Offline
|
a propósito o lazy loading é o padrão, oq não é padrão é o eager, esse sim traz toda a coleção sempre que você trouxer um entidade...
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/07/2010 22:48:24
|
breno500as
Virtual Machine Man
Membro desde: 11/10/2007 17:53:07
Mensagens: 614
Localização: Belo Horizonte - MG
Offline
|
jakefrog wrote:
não sei para JDBC ou outras camadas de acesso a banco.
Apenas com JDBC não tem como ...
brunoskrebs wrote:
1 - todas as vezes que eu carregar um usuário ele já vai carregar os perfis. e eu não quero isso, quero que a minha consulta especifica para trazer usuários com perfis faça isso...
Todas as vezes que você carregar um Usuario os Perfis serão carregados se o relacionamento não estiver marcado como LAZY ... Você tem que entender que se você marcar Perfis como LAZY e fizer um from na tabela de Usuario, não será feito um select na tabela de Perfis.
brunoskrebs wrote:
... um só select ao banco de dados.
Aí vai depender das suas regras de négocio... Independente de como estiver marcado(EAGER ou LAZY) o relacionamento, se você sempre precisar buscar um Perfil para um Usuario logicamente sempre será feito mais de um select no banco de dados.... O que você pode fazer é adiar essa busca marcando o relacionamento como LAZY, e quando você achar necessário acessar os Perfis (claro que você deve acessa-los antes da sua Session ser fechada para o Hibernate através do Proxy
fazer o select de busca dos perfis).
brunoskrebs wrote:
2 - o fetchtype eager não vai fazer com que apenas um select traga os usuários com seus devidos perfis.
Correto, o EAGER irá fazer um select tbm na tabela de perfis (caso você faça um from em Usuario) ...
brunoskrebs wrote:a propósito o lazy loading é o padrão, oq não é padrão é o eager, esse sim traz toda a coleção sempre que você trouxer um entidade...
Você está errado ... O padrão ou default em um relacionamento é o EAGER, para mais detalhes consulte a documentação ....
This message was edited 2 times. Last update was at 18/07/2010 22:56:53
|
Sun Certified Java Programmer 5.0
Sun Certified Web Component Developer 5.0
Sun Certified Business Component Developer 5.0 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/07/2010 12:17:38
|
brunoskrebs
JavaBaby
Membro desde: 01/09/2004 15:25:57
Mensagens: 75
Offline
|
http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/annotations/CollectionOfElements.html
http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-fetching
Consultando a documentação. Como eu disse o default é o LAZY.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/07/2010 12:56:30
|
breno500as
Virtual Machine Man
Membro desde: 11/10/2007 17:53:07
Mensagens: 614
Localização: Belo Horizonte - MG
Offline
|
Tem razão... Vi agora que você está utilizando a anotação @CollectionOfElements e que o default é realmente LAZY .....
|
Sun Certified Java Programmer 5.0
Sun Certified Web Component Developer 5.0
Sun Certified Business Component Developer 5.0 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 19/07/2010 13:42:16
|
brunoskrebs
JavaBaby
Membro desde: 01/09/2004 15:25:57
Mensagens: 75
Offline
|
na verdade não só o @collectionofelements mas como o hibernate utiliza o lazy por default nas collections...
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 21/07/2010 09:42:46
|
derlon
JavaTeenager
Membro desde: 12/12/2009 14:07:01
Mensagens: 150
Offline
|
brunoskrebs wrote:...Consultando a documentação. Como eu disse o default é o LAZY.
Obs.: o tipo default de Loading vai depender do tipo de Relacionamento (cardinalidade, etc.). @brunoskrebs, Em vez de usar JPAQL, pq q vc não usa 'Criteria' q, além de ser muito + fácil de usar (e + OO), ainda vc pode definir o tipo de FetchMode (Eager ou Lazy) q quiser?!!
This message was edited 1 time. Last update was at 21/07/2010 10:06:50
|
|
|
 |
|
|