[Resolvido]Hibernate (JPA) - Função substring() HQL não converte para Firebird

Galera,

Estou precisando de ajuda para resolver um problema. Estou fazendo uma consulta com Hibernate através de HQL, porém estou tendo dificuldade com a função substring().

Em meu select, tenho um atributo do tipo String mapeado como @Lob, onde no banco de dados (Firebird), é do tipo Blob sub_type 1. O problema é quando utilizo um group by, ele retorna um erro:

[code]SQL Message : -413
Overflow occurred during data type conversion.

Engine Code : 335544334
Engine Message :
conversion error from string “BLOB”[/code]

Então pesquisei sobre este erro, e descobri que o Firiberd não suporta fazer este tipo de group by ou order by em campo BLOB, então com a função

O problema é resolvido, o select funciona normalmente no banco de dados, porém ao tentar utilizar a mesma função do Hibernate

O Hibernate não converte corretamente para o banco Firebird, ao invés de criar a QUERY com

ele deixa da mesma forma que foi escrito em HQL

O que gera erro de sintaxe no Firebird.
Alguém já passou por algum problema parecido, preciso de uma solução, não estou conseguindo encontrar, já li a documentação do Hibernate e do EJB-QL, a função está utilizada corretamente. Por favor, se alguém souber qual ou problema ou se tiver uma outra alternativa para contornar o problema fico muito grato.

Já procurei no fórum, mas não achei nada referente a este problema ou semelhante.

Obrigado…

No log em que mostra o SQL gerado, está montrando assim: substring(atributo, int, int)

Muito estranho, posta ai a sua consulta, como vc fez ela em HQL.

HQL

select new pacote.ReportEntrega( entrega.id, entrega.motorista.nome, entrega.veiculo.descricao, entrega.dataSaida, entrega.horaSaida, entrega.dataRetorno, entrega.horaRetorno, entrega.kmInicial, entrega.kmFinal, entregaNota.ordem, entregaNota.chaveEntregaNotas.notaSaida.numero, entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.razaoSocial, entregaNota.chaveEntregaNotas.notaSaida.totalNota, concat(entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.tipoLogradouro.sigla, ' ', entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.logradouro, 'N ', entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.numero), entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.bairro, concat(entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.cidade, '/', entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.cidade.uf.sigla), entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.cep, substring(entregaNota.observacao,1, 10), notaSaidaItem.produto.id, notaSaidaItem.produto.descricao, sum(notaSaidaItem.quantidade)) from Entrega entrega join entrega.entregaNotas entregaNota join entregaNota.chaveEntregaNotas.notaSaida.notaSaidaItens notaSaidaItem group by entrega.id, entrega.motorista.nome, entrega.veiculo.descricao, entrega.dataSaida, entrega.horaSaida, entrega.dataRetorno, entrega.horaRetorno, entrega.kmInicial, entrega.kmFinal, entregaNota.ordem, entregaNota.chaveEntregaNotas.notaSaida.numero, entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.razaoSocial, entregaNota.chaveEntregaNotas.notaSaida.totalNota, concat(entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.tipoLogradouro.sigla, ' ', entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.logradouro, 'N ', entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.numero), entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.bairro, concat(entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.cidade, '/', entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.cidade.uf.sigla), entregaNota.chaveEntregaNotas.notaSaida.notaSaidaCliente.cep, substring(entregaNota.observacao,1, 10), notaSaidaItem.produto.id, notaSaidaItem.produto.descricao order by entrega.id, entregaNota.ordem, notaSaidaItem.produto.id

Código gerado pelo hibernate

select entrega0_.id as col_0_0_, motorista4_.nome as col_1_0_, veiculo5_.descricao as col_2_0_, entrega0_.dataSaida as col_3_0_, entrega0_.horaSaida as col_4_0_, entrega0_.dataRetorno as col_5_0_, entrega0_.horaRetorno as col_6_0_, entrega0_.kmInicial as col_7_0_, entrega0_.kmFinal as col_8_0_, entreganot1_.ordem as col_9_0_, notasaida2_.numero as col_10_0_, notasaidac8_.razaoSocial as col_11_0_, notasaida2_.totalNota as col_12_0_, (tipolograd12_.sigla||' '||notasaidac8_.logradouro||'N '||notasaidac8_.numero) as col_13_0_, notasaidac8_.bairro as col_14_0_, (notasaidac8_.cidade_id||'/'||uf25_.sigla) as col_15_0_, notasaidac8_.cep as col_16_0_, substring(entreganot1_.observacao, 1, 10) as col_17_0_, notasaidai3_.produto_id as col_18_0_, produto28_.descricao as col_19_0_, sum(notasaidai3_.quantidade) as col_20_0_ from Entrega entrega0_ inner join EntregaNotas entreganot1_ on entrega0_.id=entreganot1_.ENTREGA_ID inner join NotaSaida notasaida2_ on entreganot1_.NOTASAIDA_ID=notasaida2_.id inner join NotaSaidaItens notasaidai3_ on notasaida2_.id=notasaidai3_.NOTASAIDA_ID, Produto produto28_, NotaSaidaCliente notasaidac8_, TipoLogradouro tipolograd12_, Cidade cidade21_, UF uf25_, Motorista motorista4_, Veiculo veiculo5_ where notasaidai3_.produto_id=produto28_.id and notasaida2_.id=notasaidac8_.NOTASAIDA_ID and notasaidac8_.tipoLogradouro_id=tipolograd12_.id and notasaidac8_.cidade_id=cidade21_.id and cidade21_.uf_id=uf25_.id and entrega0_.motorista_id=motorista4_.id and entrega0_.veiculo_id=veiculo5_.id group by entrega0_.id , motorista4_.nome , veiculo5_.descricao , entrega0_.dataSaida , entrega0_.horaSaida , entrega0_.dataRetorno , entrega0_.horaRetorno , entrega0_.kmInicial , entrega0_.kmFinal , entreganot1_.ordem , notasaida2_.numero , notasaidac8_.razaoSocial , notasaida2_.totalNota , (tipolograd12_.sigla||' '||notasaidac8_.logradouro||'N '||notasaidac8_.numero) , notasaidac8_.bairro , (notasaidac8_.cidade_id||'/'||uf25_.sigla) , notasaidac8_.cep , substring(entreganot1_.observacao, 1, 10) , notasaidai3_.produto_id , produto28_.descricao order by entrega0_.id, entreganot1_.ordem, notasaidai3_.produto_id

Obrigado…

Aparentemente isso está correto: substring(entreganot1_.observacao,1,10)

Tem certeza que o problema é aqui?

Se vc pegar esse SQL gerado pelo hibernate, e executa-lo direto no firebird, sem utilizar o substring, da certo?

Tenho, colei esta query no FlameRobin, e dá um erro.

Pesquisando sobre esta função no Firebird, vi que não é desta forma no Firebird, a sintaxe desta função no Firebird é

Substitui desta forma e funciona no FlameRobin. Mas da forma que o Hibernate faz dá o seguinte erro.

[code]SQL Message : -104
Invalid token

Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 19, column 36
,[/code]

Romarcio

Você tem alguma idéia do que pode estar acontecendo?

Não tinha me ligado nesse problema exclusivo do firebird.

Realmente, existe um bug no Hibernate nesse caso.

Encontrei postado aqui: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4053?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#issue-tabs o relato do problema, eu uma possivel solução.

No caso, vc teria que baixar o projeto do hibernate e alterar essa linha citada.

Eu tenho aqui o hibernate 3.5.3-final e ela se encontra no diretório: hibernate-distribution-3.5.3-Final\project\core\src\main\java\org\hibernate\dialect

Porém, não fica no dialect FirebirdDialect.java e sim InterbaseDialect.java, que é extendido pelo FirebirdDialect.java.

Vc teria que alterar e gerar um novo jar do hibernate.

Muito obrigado pela ajuda.

Entrei no site do Hibernate, e liberaram hoje a versão 3.6.0 Final. Vou ver se foi corrigido este bug, no link que você me passou estava como prioridade alta.

http://sourceforge.net/projects/hibernate/files/hibernate3/

Assim que tiver uma certeza posta a melhor solução adotada e coloco como resolvido.

Obrigado pela ajuda…

PS: Como coloco resolvido? É só alterar o título mesmo?

[quote=fbrissi]Muito obrigado pela ajuda.

Entrei no site do Hibernate, e liberaram hoje a versão 3.6.0 Final. Vou ver se foi corrigido este bug, no link que você me passou estava como prioridade alta.

http://sourceforge.net/projects/hibernate/files/hibernate3/

Assim que tiver uma certeza posta a melhor solução adotada e coloco como resolvido.

Obrigado pela ajuda…

PS: Como coloco resolvido? É só alterar o título mesmo?[/quote]

Ok, posta a solução caso consiga.

Para colocar como Resolvido, edite seu 1° post e ao lado do titulo coloque [Resolvido]

Para aqueles que tiverem o mesmo problema que eu. O problema foi solucionado da seguinte maneira.
(Mas atenção, apenas para versão hibernate-distribution-3.5.2-Final)

Abra o jar hibernate3.jar e vá para pasta /org/hibernate/dialect/

substitua o arquivo InterbaseDialect.class pelo arquivo com o mesmo nome dentro do zip anexado.

Para quem quiser saber a alteração feita, segue em anexo os .java original e o alterado comentada a linha alterada.
A alteração foi simples, apenas uma linha foi adicionada ao código.

Espero que possa ajudar alguém…

Obrigado por todos que colaboraram para que este problema fosse solucionado.

OBS: Não tenho certeza, mas me parece que este erro continua na versão 3.6.0 Final do Hibernate.