Resolvi utilizar o pool de conexões oferecido pelo C3P0 mas estou tendo problemas ao utilizá-lo com o Banco de Dados Oracle.
O grande problema, é que eu preciso recuperar o CURSOR retornado por uma função que está no Banco na linha abaixo:
O meu problema é quando tento recuperar dados do cursor retornado por uma função Oracle.
Quando eu envio comando SQL ao banco, consigo obter os dados com sucesso.
Aqui está parte do método que tenta recuperar dados do cursor.
CallableStatement stmConsulta = null;
Connection conexao = null;
try
{
conexao = new ConexaoC3P0().getConexao();
stmConsulta = conexao.prepareCall(funcaoOracleObtemBeneficiarios);
//Enviando dados para para a Função Oracle F_OBTEM_BENEFICIARIOS
setParametrosGetBeneficiario(stmConsulta, unimedCodigo, beneficiarioCodigo);
stmConsulta.execute();
//1 - Sucesso na consulta - Função Oracle
if (stmConsulta.getInt(1) == 1)
{
//Receberá o Cursor contendo o resultado da Stored Procedure no Banco
ResultSet rs = ( (OracleCallableStatement) stmConsulta).getCursor(6);
if(rs.next())
{
beneficiario = new Beneficiario();
//Essas linhas poderão lançar uma SQLException
beneficiario.setCodigoBeneficiario( rs.getString(1) );
beneficiario.setNomeBeneficiario( rs.getString(2) );
beneficiario.setDataNascimentoBeneficiario( rs.getDate(3) );
beneficiario.setMatriculaBeneficiario( rs.getString(4) );
...
G
garcia-jj
Não conheço muito bem o c3p0, mas creio que ao invés de trazer teu tradicional OracleStatement, ele retorna um proxy, por isso o ClassCastException. Indico a você dar uma analisada na documentação, pois pode haver algum wordaround para trabalhar sem os proxies ou outra forma de retornar o cursor.
Além disso essa linha aqui está um pouco confusa.
Não deveria ser isso aqui?
FightSurf_George_Mai
Eu pego estes valores de um arquivo properties. Os substitui aqui somente para essa dúvida.
Obrigado pela dica!
Paulo_Silveira
voce precisa mesmo invocar esse metodo getCursos(6)? nao ha como fazer com os metodos ja expostos pela interface CallableStatement?
o c3p0 cria uma proxy na frente de todo Statement, por isso o cast nao funciona. se precisar mesmo, faca primiro o cast para NewProxyCallableStatement e ai veja se ha algum metodo como getDelegate() que devolva um CallableStatement. Entao pegue esse callable e faca o cast para o do Oracle
G
garcia-jj
Olhando seu primeiro código a impressão que tenho é que sempre que você chama o métod getConexao você recria o pool e o mata após a execução. Ou seja, você não está na verdade tento um pool, pois você cria e logo mata ele.
Como eu te disse, nunca usei o c3p0, porém pelo meu conhecimento em Java creio que você deva inicializar o c3p0 e deixa-lo como instancia statica, e sempre buscar as conexões dele via método estático, lembrando de sempre fechar as conexões via thread-local ou manualmente.
Você usa alguma ferramenta ORM? Sua aplicação é web? Se for web, você pode usar algum datasource direto do servidor? Fica mais prático e simples de configurar.
FightSurf_George_Mai
Obrigado pelas observações.
Garcia, o esquema de tornar o pool estático é válido. Deverá ser tratado dessa forma.
Estou tentando fazer um refactoring de alguns métodos aqui no trabalho para utilizarmos o pool do C3P0… Aí estou indo por partes.
Paulo, irei procurar qual cast fazer para isso.
O que dificulta é porque eu tenho mesmo que recuperar dados por um cursor retornado por uma função oracle, colocando esse cursor no Resultset e navegando através dele.
Abraço a todos.
A
andreban
Não sei se vc está usando java 1.6 e se o C3P0 implementa corretamente esses métodos, mas vc pode tentar o método
pra saber se dá pra pegar o CalableStatement original. E se o resultado for true, use
FightSurf_George_Mai
Eu baixei uma apostila do Hibernate (mauricio linhares) e vi que podemos fazer com que o CP30 trabalhe com ele apenas informando algumas linhas no arquivo hibernate.cfg.xml.
É isso que acontece mesmo? Acho que irei por essa alternativa.