Hibernate x Query [Resolvido]

Como declarar a seguinte Query com Hibernate:

SELECT t.* FROM (
      SELECT level,
             codigo,
             rpad(' ',(level*5))||descricao Opcao,
             (SELECT DECODE(count(*),0,0,1) 
                FROM PROFILE_SECURITY S
               WHERE S.CODIGO_MENU = M.CODIGO) flag
          FROM MENU M
        CONNECT BY PRIOR CODIGO = PAI START WITH PAI = 0
      )t
WHERE t.flag = 1

E também:

sql = cnct.conn.prepareStatement
				      ("  SELECT distinct t.* " +
				       "    FROM( "+
				       "        SELECT w.id_workflow, "+ 
				       "			 w.descricao,  "+
				       "			 w.quantidade_aprovacoes, "+ 
				       "			 NVL(w.criterio_inicio,' ')criterio_inicio, "+ 
				       "			 Decode(w.modo_notificacao,1,'Por Evento','Agrupado'), "+ 
				       "			 w.tempo_limite || ' minutos', "+ 
				       "			 w.id_tabela_base, "+ 
				       "			 w.id_grupo_workflow,  "+
				       "			 gw.descricao grupo, "+ 
				       "			 tb.descricao tabela, " +
				       "         	 Decode(w.prioridade,null,' ',w.prioridade)prioridade "+  
				       "        FROM wf_workflow w, "+ 
				       "	 		 wf_grupo_workflow gw, "+ 
				       "			 wf_tabela_base tb, "+ 
				       "			 wf_workflow_item wi "+ 
				       "	   WHERE w.id_grupo_workflow = ? "+ 
				       "  		 AND w.id_workflow       = wi.id_workflow "+ 
				       " 		 AND w.id_grupo_workflow = gw.id_grupo_workflow "+ 
				       "		 AND w.id_tabela_base 	 = tb.id_tabela_base "+ 
				       "		 AND wi.username         = Upper(?) "+ 
				       
				       " UNION ALL "+
				       
				       "	  SELECT w.id_workflow, "+ 
				       "			 w.descricao,  "+
				       "			 w.quantidade_aprovacoes, "+ 
				       "			 NVL(w.criterio_inicio,' ')criterio_inicio, "+ 
				       "			 Decode(w.modo_notificacao,1,'Por Evento','Agrupado'), "+ 
				       "			 w.tempo_limite || ' minutos', "+ 
				       "			 w.id_tabela_base, "+ 
				       "			 w.id_grupo_workflow,  "+
				       "			 gw.descricao grupo, "+ 
				       "			 tb.descricao tabela, " +
				       "         	 Decode(w.prioridade,null,' ',w.prioridade)prioridade "+  
				       " 		FROM wf_workflow w, "+ 
				       " 		 	 wf_grupo_workflow gw, "+ 
				       "		 	 wf_tabela_base tb "+
				       "	   WHERE w.id_grupo_workflow = ? "+ 
				       " 		 AND w.id_grupo_workflow = gw.id_grupo_workflow "+ 
				       "		 AND w.id_tabela_base 	 = tb.id_tabela_base "+ 
				       "		 AND Not Exists (Select 1 From wf_workflow_item i "+ 
				       "               			  Where i.id_workflow = w.id_workflow) "+  
				       "	 )t "+  
				       "ORDER BY t.prioridade, " +
				       "         t.id_workflow");

Tem como ou terei que continuar usando prepareStatement ?

Valew.

A resposta deve estar aqui:
http://www.hibernate.org/hib_docs/entitymanager/reference/en/html/query_native.html

e aqui:
http://www.hibernate.org/hib_docs/v3/reference/en/html/querysql.html

Se o que está nessas páginas não ajudar (pq os seus sql’s são assustadores!), não sei o que pode te ajudar…

(talvez só uma benzedeira q tem lá em Piracicaba, eheheheh)

:wink:

Acredito que a melhor forma é primeiro ver se você conseguiu conveter suas tabelas relacionais para Objetos, ai pode ficar mais simples chegar a conclusão de como fazer com o Query do Hibernate, a outra opção é continuar mandando a query usando as querys nativas e mapeando o resultado para objeto, o ruim disto é que vc perde a portabilidade do programa. Realmente as suas querys são bem complexas mais fica dificil chegar a uma conclusão sobre elas sem saber quais informações estão sendo cruzadas e principalmente qual o resultado final esperado.

Temos uma situação parecida na empresa em que trabalho, pois como o sistema é integrado e multi-plataforma (tem VB, Centura, SqlWindows, Mainframe e Java), a arquitetura do sistema foi feita de um jeito que a maior parte da camada de negócios foi implementada em um banco de dados Oracle.

A solução (paleativa, mas que se mostrou bem robusta) foi utilizar um framework de mapeamento Objeto x SQL ao invés do Objeto x Banco Relacional. Nós estamos utilizando o IBatis, abstraído através do pattern DAO.

A nossa intenção é posteriormente avançar para JPA/Hibernate, mas devido a complexidade dos SQLs, ainda acho o IBatis uma melhor solução, pois nós temos maior controle sobre a performance das queries no Oracle, e também temos a vantagem de mantê-las em separado dos objetos de negócio, nos arquivos XML utilizados pelo framework.

[quote=marceloplis]Como declarar a seguinte Query com Hibernate:

SELECT t.* FROM (
      SELECT level,
             codigo,
             rpad(' ',(level*5))||descricao Opcao,
             (SELECT DECODE(count(*),0,0,1) 
                FROM PROFILE_SECURITY S
               WHERE S.CODIGO_MENU = M.CODIGO) flag
          FROM MENU M
        CONNECT BY PRIOR CODIGO = PAI START WITH PAI = 0
      )t
WHERE t.flag = 1

Valew.[/quote]

Penso em somente duas soluções para este caso

  1. Usar query nativa como diz o neófito, porém acredito que esta solução vai deixar sua aplicação atrelado ao Banco, e que me lembro só oracle faz isto, estou errado ?

  2. Usar java para resolver isto. Veja bem, esta é um SQL recursiva, então ao invés de você tentar traduzir ela para o Hibernate você vai conseguir o mesmo efeito fazendo um método recursivo no java. Eu também tinha uma SQL igual a sua para montar o MENU no Delphi, em java preferi traduzir ela com método recursivo.

Porém a solução número 2 tem problemas de desempenho com árvores muito grandes, deixando o banco resolver como na solução 1 sua aplicação terá ganhos consideráveis de performance, mas no seu caso, aparentemente é um MENU, então vale mais a pena a solução 2 mesmo.

[]s

Bom, já que a maioria citou em usar query nativa, alguem teria um exemplo que preenche um List ?? e como atrelar este List à minha classe VO ??

Valew.

Funcionou:

public List<Menu> listaMenu(Menu menu){
		String sql = " SELECT level, " + 
                                      "        pai, " +
					 "        codigo, " +
					 "        tipo, " +
					 "        rpad(' ',(level*5))||descricao Descricao " +
					 "   FROM ps_menu m " +
					 "  WHERE m.pai = "+ menu.getCodigo() +
					 "CONNECT BY PRIOR CODIGO = PAI START WITH PAI = 0 ";

		return getSession().createSQLQuery(sql)
		 	.addEntity(Menu.class)
		 	.list();
	}