[RESOLVIDO] Função SQL chamada no HQL

Olá pessoal.

Criei uma função SQL e preciso chamar via HQL (Uso Spring Data).
Dei uma pesquisada e descobri que preciso escrever o meu próprio Dialeto.

Porém não encontrei como fazer isto.
Alguém sabe como?

Conhece orientação a objetos?
Herança é um dos recursos que você pode utilizar, junto de polimorfismo.
Think about it

[quote=drsmachado]Conhece orientação a objetos?
Herança é um dos recursos que você pode utilizar, junto de polimorfismo.
Think about it[/quote]

Opa…

Sim, imagino que deve ser possível extender o Dialeto do Hibernate…
Depois a solução deve ser utilizar a sua classe na configuração do Hibernate…

"hibernate.dialect" ... "seu.pacote.sua.classe.PostgreSQLDialect"

Mas não sei como implementa…
Sabe drsmachado?

Fiz uma vez para resolver um problema de encoding.

package br.com.projeto.intro_jpa.util;

import org.hibernate.dialect.MySQL5Dialect;

public class MyCustomDialect extends MySQL5Dialect {
	@Override
	public String getTableTypeString() {
		return " DEFAULT CHARSET=utf8";
	}
}

Como usava JPA, fiz isso no persistence.xml

<!-- property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /-->
<property name="hibernate.dialect" value="br.com.projeto.intro_jpa.util.MyCustomDialect" />

Como pode perceber, foi apenas o encoding que alterei, mas, até onde vi, nenhum método é marcado como final, o que causaria a impossibilidade de sobrescrita.
Ou seja, você pode criar um e alterar os métodos em que haja necessidade, os demais, pode mantê-los intactos (eu recomento manter).

Pois é…
isso é de se imaginar…

mas acabei descobrindo…
no construtor basta fazer:


registerFunction("current_timestamp", new NoArgSQLFunction(Hibernate.TIMESTAMP) );
registerFunction("date", new StandardSQLFunction(Hibernate.DATE) );

Não seria mais fácil usar native query para realizar tudo? :roll:

Foi o que pensei, mas reinventar a roda pode parecer mais interessante…

Foi o que pensei, mas reinventar a roda pode parecer mais interessante…[/quote]

Não é,
pois estou usando Spring Data e não quero descer o nivel…

A query também é bem complicadinha!
Vou tentar escrever o Dialeto. Se nao conseguir,
nao vou ter como fugir do SQL.

Obrigado pela ajuda!

Foi o que pensei, mas reinventar a roda pode parecer mais interessante…[/quote]

Não é,
pois estou usando Spring Data e não quero descer o nivel…

A query também é bem complicadinha!
Vou tentar escrever o Dialeto. Se nao conseguir,
nao vou ter como fugir do SQL.

Obrigado pela ajuda!

[/quote]Vc acha escrever um dialeto mais simples que uma query? WTF?! :shock:

[quote=Hebert Coelho]
Vc acha escrever um dialeto mais simples que uma query? WTF?! :shock: [/quote]

Sim… Uma linha de codigo resolvi meu problema!!!

registerFunction("replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING));

[quote=Noturno192][quote=Hebert Coelho]
Vc acha escrever um dialeto mais simples que uma query? WTF?! :shock: [/quote]

Sim… Uma linha de codigo resolvi meu problema!!!

registerFunction("replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING)); [/quote]Legal.

Mas essa é a unica alteração no projeto inteiro? Quem é o registerFunction?

Boa tarde galera, estou com uma dúvida em relação a sobrescrever o dialeto.

Tenho uma consulta utilizando construtor como segue abaixo:

Ex DAO:


MyCustomDialect my = new MyCustomDialect();
my.registerFunction("funcao",new StandardSQLFunction("FN_SUBELEMENTO_CONCAT(e.id)"));//passo um param aqui...
			
			
StringBuffer sql = new StringBuffer();

sql.append(" select new Empenho (id, funcao) from Empenho e");

Construtor


public Empenho(Long id ,String subElemento){
		System.err.println(subElemento);
	}

Essa minha função faz um select no banco e me retorna uma string formatada em um padrão que nos precisamos aqui na empresa.

create or replace 
FUNCTION FN_SUBELEMENTO_CONCAT (empenhoId in number) RETURN VARCHAR2 AS 
  
  v_retorno varchar2(4000);
  iCont integer:=0;
  
BEGIN
    
    FOR x IN (SELECT s.codigo_sub_elemento 
          FROM empenho_sub_elemento es
          join sub_elemento s on es.sub_elemento = s.id_sub_elemento where es.empenho = empenhoId) LOOP
          if v_retorno is null then
              v_retorno:= x.codigo_sub_elemento;  
          else
              v_retorno:= v_retorno ||'-'|| x.codigo_sub_elemento;  
          end if;
          iCont:= iCont+1;
          if iCont > 10 then
            exit;
          end if;
    END LOOP;
   
   return v_retorno;
   
END FN_SUBELEMENTO_CONCAT;