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

9 respostas
fbrissi

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:
SQL Message : -413
Overflow occurred during data type conversion.

Engine Code    : 335544334
Engine Message :
conversion error from string "BLOB"
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
SUBSTRING(NOME_CAMPO FROM VALOR_INICIAL FOR VALOR_FINAL)
O problema é resolvido, o select funciona normalmente no banco de dados, porém ao tentar utilizar a mesma função do Hibernate
substring(atributo, int, int)
O Hibernate não converte corretamente para o banco Firebird, ao invés de criar a QUERY com
SUBSTRING(NOME_CAMPO FROM VALOR_INICIAL FOR VALOR_FINAL)
ele deixa da mesma forma que foi escrito em HQL
substring(atributo, int, int)

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.....

9 Respostas

romarcio

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.

fbrissi

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…

romarcio

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?

fbrissi

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 é
substring(entreganot1_.observacao from 1 for 10) as col_17_0_,
Substitui desta forma e funciona no FlameRobin. Mas da forma que o Hibernate faz dá o seguinte erro.
SQL Message : -104
Invalid token

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

Romarcio

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

romarcio

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.

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?

romarcio

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?

Ok, posta a solução caso consiga.

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

fbrissi

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.

Criado 14 de outubro de 2010
Ultima resposta 14 de out. de 2010
Respostas 9
Participantes 2