Pessoal estou com um problema aqui que não consigo resolver nem fodendo !!! Quando eu executo esse script em um banco de dados SQL Server funciona normal, agora quando estou executando no Postgrees não vai de maneira alguma, não da erro e não faz update, alguem tem alguma ideia ?
intid=35;booleanretorno=false;StringresDirectory=gb.getPropertyAplication("Path")+gb.getPropertyAplication("ResDirectory");StringnameRel="";StringBuffersql=newStringBuffer("SELECT titulo, xml FROM "+gb.getPropertyAplication("RelatoriosJava")+" WHERE idrelatorio = ");sql.append(Query.toSQL(id,Query.Number_TYPE));ResultSetrs=Query.getResultSet(sql.toString(),gb.st);if(rs==null)thrownewException("Relatório não existe");if(rs.next()){try{nameRel=rs.getString("titulo");net.sf.jasperreports.engine.design.JasperDesignjasperDesign=net.sf.jasperreports.engine.xml.JRXmlLoader.load(newjava.io.ByteArrayInputStream((rs.getString("xml")).getBytes("UTF-8")));jasperDesign.addImport("com.sil.util.*");net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile(jasperDesign,resDirectory+"/"+nameRel+".jasper");InputStreamisLayout=newFileInputStream(resDirectory+"/"+nameRel+".jasper");PreparedStatementpStUpdate=gb.st.getConnection().prepareStatement("UPDATE "+gb.getPropertyAplication("RelatoriosJava")+" set layout = ? WHERE idrelatorio = ?");pStUpdate.setBinaryStream(1,isLayout,isLayout.available());pStUpdate.setInt(2,id);pStUpdate.execute();isLayout.close();Filef=newFile(resDirectory+"/"+nameRel+".jasper");f.delete();if(pStUpdate!=null)pStUpdate.close();if(rs!=null)rs.close();retorno=true;}catch(Exceptione){retorno=false;}}
Ele cria o arquivo Jasper normalmente, mas na hora de fazer o update não vai !!!
qual o erro e qual o tipo de dados que está usando no postgres?
luisbizzan
Então evefuji, o incrivel que não da erro, a coluna ao qual eu quero gravar é do tipo bytea, estou tentando salvar o .jasper gerado pelo JasperReports dentro de uma coluna da tabela, no SQL Server essa coluna é do tipo “image”, e a gravação ocorre normalmente, ja no postgres que é a bytea não apresenta erro porem tb não salva, estou desconfiado que seja o tamanho do arquivo, mas meu arquivo tem apenas 20KB, estranho né? Será q tem como eu verificar a sintaxe SQL que ele esta tentando rodar no banco ?
Abraço
E
evefuji
acho que o problema está no:
isLayout.available()
Se me lembro bem deveria ser o lenght() do arquivo.
luisbizzan
Bom ja fiz esse teste mais irei realizar novamente para verificar se ouve correção e ja lhe respondo ok?
Abraço
luisbizzan
Bom cara realizei o teste como eu havia lhe falado e nada olha como ficou a implementação:
intid=35;booleanretorno=false;StringresDirectory=gb.getPropertyAplication("Path")+gb.getPropertyAplication("ResDirectory");StringnameRel="";StringBuffersql=newStringBuffer("SELECT titulo, xml FROM "+gb.getPropertyAplication("RelatoriosJava")+" WHERE idrelatorio = ");sql.append(Query.toSQL(id,Query.Number_TYPE));ResultSetrs=Query.getResultSet(sql.toString(),gb.st);if(rs==null)thrownewException("Relatório não existe");if(rs.next()){try{nameRel=rs.getString("titulo");net.sf.jasperreports.engine.design.JasperDesignjasperDesign=net.sf.jasperreports.engine.xml.JRXmlLoader.load(newjava.io.ByteArrayInputStream((rs.getString("xml")).getBytes("UTF-8")));jasperDesign.addImport("com.sil.util.*");net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile(jasperDesign,resDirectory+"/"+nameRel+".jasper");Filef=newFile(resDirectory+"/"+nameRel+".jasper");InputStreamisLayout=newFileInputStream(f);//InputStream isLayout = new FileInputStream(resDirectory+"/"+nameRel+".jasper");PreparedStatementpStUpdate=gb.st.getConnection().prepareStatement("UPDATE "+gb.getPropertyAplication("RelatoriosJava")+" set layout = ? WHERE idrelatorio = ?");pStUpdate.setBinaryStream(1,isLayout,(int)f.length());pStUpdate.setInt(2,id);pStUpdate.executeUpdate();isLayout.close();//f.delete();if(pStUpdate!=null)pStUpdate.close();if(rs!=null)rs.close();retorno=true;}catch(Exceptione){if(true)thrownewException(e.toString());retorno=false;}}
Estou achando que pode ser meu drive de conexao viu, pois eu inclui a informação na coluna da tabela via banco mesmo, e na leitura esta dando uma mensagem “2”, e no stacktrace esta apresentando um metodo do JDBC. Mas é uma ideia só, vc tem mais alguma ai ?
Abraço
E
evefuji
vc pode fazer um System.out.println(pStUpdate.toString()) para ver o SQL que ele gera. (mas nunca monitorei isso com BinaryStream, acredito que vá colocar uma String Hexadecimal)
Isso não deve ter nada a ver, mas eu costumo utilizar o executeUpdate() no lugar do execute(). (se me lembro bem, a única diferença é que retorna o número de linhas, mas já vi alguns drivers/sgbd não funcionarem bem com o execute para fazer update/insert, por não dar commit)
O exemplo usando BinaryStream me parece estar semelhante.
luisbizzan
Cara fiz como vc tinha me falado, coloquei o commit mudei para pStUpdate.executeUpdate(); e nada, o ingraçado que rodo isso no postgres e ele faz o update, agora buscanco pelo driver nao vai !!! ele até me apresenta a excessão da sintaxe
Mas mesmo assim não vai, estou pensando em trocar o tipo de dados para varchar de 8000 e ver como ele faz,
tem alguma outra ideia ?
Abraço
E
evefuji
mas o executeUpdate retornou quanto?
luisbizzan
retornou 1 ainda, mas a coluna nada de atualizar !!! ta muito estranho isso !!!
E
evefuji
a conexão está com autocommit? Se você tenta recuperar nessa mesma conexão o objeto através de uma consulta ele retorna certo?
luisbizzan
Eu inseri um autocommit(false), e depois commit abaixo do executeUpdate, e busquei o resultado apos isso !
intid=35;booleanretorno=false;StringresDirectory=gb.getPropertyAplication("Path")+gb.getPropertyAplication("ResDirectory");StringnameRel="";StringBuffersql=newStringBuffer("SELECT titulo, xml FROM "+gb.getPropertyAplication("RelatoriosJava")+" WHERE idrelatorio = ");sql.append(Query.toSQL(id,Query.Number_TYPE));ResultSetrs=Query.getResultSet(sql.toString(),gb.st);if(rs==null)thrownewException("Relatório não existe");if(rs.next()){Connectioncn=gb.getCn();cn.setAutoCommit(false);try{nameRel=rs.getString("titulo");net.sf.jasperreports.engine.design.JasperDesignjasperDesign=net.sf.jasperreports.engine.xml.JRXmlLoader.load(newjava.io.ByteArrayInputStream((rs.getString("xml")).getBytes("UTF-8")));jasperDesign.addImport("com.sil.util.*");net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile(jasperDesign,resDirectory+"/"+nameRel+".jasper");Filef=newFile(resDirectory+"/"+nameRel+".jasper");InputStreamisLayout=newFileInputStream(f);//InputStream isLayout = new FileInputStream(resDirectory+"/"+nameRel+".jasper");PreparedStatementpStUpdate=gb.st.getConnection().prepareStatement("UPDATE "+gb.getPropertyAplication("RelatoriosJava")+" set layout = ? WHERE idrelatorio = ?");pStUpdate.setBinaryStream(1,isLayout,(int)f.length());pStUpdate.setInt(2,id);inti=pStUpdate.executeUpdate();isLayout.close();//f.delete();//if (pStUpdate != null) pStUpdate.close();if(rs!=null)rs.close();retorno=true;cn.commit();if(true)thrownewException(i+"..."+pStUpdate.toString());}catch(Exceptione){cn.rollback();retorno=false;if(true)thrownewException(e.toString());}finally{cn.setAutoCommit(true);}}
Vc fala pra fazer um select dentro dela mesmo para ver oque ele retorna ?
luisbizzan
Cara estou achando que o campo bytea do postgres, pois fiz o teste no dql server e funciona normalmente… tem alguma ideia de que datatype poço testar para mudar esse bytea ?
E
evefuji
olhei na doc do postgre, tem também o OID, que você pode usar o código para LargeObjects que tem naquele link que te mandei lá em cima.
Faz um teste, atualiza junto nessa consulta um outro campo da tabela (inclui um só para fazer o teste, por exemplo, e adiciona a data), e vê se esse campo atualiza. Olha também nos logs do banco.
luisbizzan
é eu gero essa ecessão pois estou executando o script no BeanShell, mas eu criei uma classe tb para fazer um teste e esta ocorrendo o mesmo problema, e ainda pior o arquivo .jasper que eu faço o update no banco de dados tem 20kb, depois eu faço um select para buscar ele novamente e gero outro arquivo .jasper, ele esta me gerando com 40kb. Basicamente dúplicando.
Olha o código:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */packagetestebytea;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.UnsupportedEncodingException;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importnet.sf.jasperreports.engine.JRException;/** * * @author LGBIZZAN */publicclassMain{/** * @param args the command line arguments */publicstaticConnectionconexao;publicstaticStringdriver="org.postgresql.Driver";publicstaticStringservidor="192.168.5.14:5432";publicstaticStringbase="motorddw";publicstaticStringlogin="smar";publicstaticStringsenha="@#smarapd#@";publicstaticStringurl="jdbc:postgresql://"+servidor+"/"+base;publicstaticvoidmain(String[]args)throwsSQLException,JRException,UnsupportedEncodingException,FileNotFoundException,IOException{intid=36;StringnameRel="";StringresDirectory="C:Temp/Teste";try{Class.forName(driver);conexao=DriverManager.getConnection(url,login,senha);}catch(ClassNotFoundExceptione){e.printStackTrace();}catch(SQLExceptions){s.printStackTrace();}StringBuffersql=newStringBuffer("SELECT titulo, xml FROM RelatoriosJava WHERE idrelatorio = "+id);PreparedStatementpSt=conexao.prepareStatement(sql.toString());ResultSetrs=pSt.executeQuery();if(rs!=null){rs.next();nameRel=rs.getString("titulo");net.sf.jasperreports.engine.design.JasperDesignjasperDesign=net.sf.jasperreports.engine.xml.JRXmlLoader.load(newjava.io.ByteArrayInputStream((rs.getString("xml")).getBytes("UTF-8")));jasperDesign.addImport("com.sil.util.*");net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile(jasperDesign,resDirectory+"/"+nameRel+".jasper");Filef=newFile(resDirectory+"/"+nameRel+".jasper");InputStreamisLayout=newFileInputStream(f);System.out.print(isLayout.available()+"\r\n"+isLayout.toString()+"\r\n");pSt=conexao.prepareStatement("UPDATE RelatoriosJava set layout = ? WHERE idrelatorio = ?");pSt.setBinaryStream(1,isLayout,(int)f.length());pSt.setInt(2,id);inti=pSt.executeUpdate();isLayout.close();System.out.print(i+"..."+pSt.toString()+"\r\n");StringBuffersql2=newStringBuffer("SELECT titulo, layout FROM RelatoriosJava WHERE idrelatorio = "+id);pSt=conexao.prepareStatement(sql2.toString());ResultSetrs2=pSt.executeQuery();if(rs2!=null){rs2.next();InputStreamipsLayout=rs2.getBinaryStream("layout");byte[]by=rs2.getBytes("layout");System.out.print(ipsLayout.available()+"\r\n"+by.length);FileOutputStreamFOS=newFileOutputStream(newFile(resDirectory+"/"+nameRel+"2.jasper"));intcount;intBUFFER=2048;byte[]dados=newbyte[BUFFER];// Efetua a leitura real e a gravação no outro arquivowhile((count=ipsLayout.read(dados,0,BUFFER))!=-1){FOS.write(by,0,count);}}}}}
Agora esse novo datatype vou dar uma olhada nele e ja ti falo !!!
luisbizzan
Achei a razão do problema no PostgreSQL 9, o byte é representado como um hexadecimal (ou seja, 16 bits), enquanto q nas versões anteriores eram 8 bits só q ao ler, o Java lê bytes de 8 bits, então ele precisa de 2 bytes pra ler 1 do PostgreSQL. Foi lançado um novo drive Version 9.0-dev800 (2010-05-11) - “Support reading the new hex escaped bytea format. (jurka)” que faz essa correção. Caso alguem precise é do baixar do site http://jdbc.postgresql.org/download.html.