C3P0 e Banco Oracle

9 respostas
FightSurf_George_Mai

Bom dia, colegas.

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:

ResultSet rs =  ( (OracleCallableStatement) stmConsulta).getCursor(6);

Mas aí é lançada uma exception

com.mchange.v2.c3p0.impl.NewProxyCallableStatement cannot be cast to oracle.jdbc.driver.OracleCallableStatement

Aqui está a minha classe que retorna a conexão:

public Connection getConexao() {
			
			Connection connection = null;
			String url = null;
			
			ComboPooledDataSource cpds = new ComboPooledDataSource();
			cpds.setDriverClass( "oracleDriver" ); //loads the jdbc driver 
			cpds.setJdbcUrl( "ur"l );
			cpds.setUser("oracleUsuario" ); 
			cpds.setPassword("oracleSenha" );
				
			connection = cpds.getConnection();
							
			return connection; 

		}//public Connection getConexao()

Alguma dica? Abraço a todos.

9 Respostas

G

Como você inicializa isso? Onde onde tem o stmConsulta?

ResultSet rs = ( (OracleCallableStatement) stmConsulta).getCursor(6);

FightSurf_George_Mai

Olá garcia.

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

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

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

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.

Criado 26 de outubro de 2009
Ultima resposta 27 de out. de 2009
Respostas 9
Participantes 4