Problema al llamar a un Procedimiento Almacenado desde Java con el uso del Framework de Spring

tema enviado por Blackcat en Java
tema iniciado el 06/10/2009
Hola, tengo un problema al obtener un tipo de dato desde un Procedimiento PL/SQL (el cual está etiquetado como IN OUT en el procediemiento) Para hacer la llamada al PL/SQL, estoy usando el framework de Spring. Por un lado tengo mi procedimiento PL/SQL, que recibe dos parámetros, uno de entrada y el otro de salida. El de salida es un cursor que tengo definido en el paquete pl/sql (ya que lo normal es que me devuelva mas de un registro) El PL/SQL tiene el siguiete aspecto: ------------------------------------------------------------------------ CREATE OR REPLACE PACKAGE PACKAGE1 AS TYPE ref_cur IS REF CURSOR; PROCEDURE myprocedure (name in varchar2, stock_cursor in out ref_cur); END PACKAGE1; / ------------------------------------------------------------------------ CREATE OR REPLACE PACKAGE BODY PACKAGE1 AS PROCEDURE myprocedure (name in varchar2, stock_cursor in out ref_cur) IS BEGIN OPEN stock_cursor FOR 'select id, name, email from users where name = '''||name||''' '; END myprocedure; END PACKAGE1; / ------------------------------------------------------------------------ en el código Java, intento lo siguiente: 1- Tengo una clase de test (Test_Example), desde la que depuro con el Eclipse. 2- Mi clase Example, es llamada desde la de test y es en la que definen los parámetros de entrada y salida, donde se compila la llamada y donde se ejecuta la llamada al procedimiento (realmente el método execute que se ejecuta es el de la clase extendida StoredProcedure del framework de spring). 3- Tengo una clase GenericProced que extiende de StoredProcedure, donde se obtiene el datasource. ------------------------------------------------------------------------- GenericProced.java ------------------ import java.util.Map; import java.util.Properties; import javax.naming.InitialContext; import javax.sql.DataSource; import org.apache.log4j.Logger; import org.springframework.jdbc.object.StoredProcedure; public abstract class GenericProced extends StoredProcedure { public GenericProced(String InitialContextFactory, String providerUrl, String urlPkgPrefixes , String pool, String procedimiento) throws Exception { super(givemeDatasource ( InitialContextFactory, providerUrl, urlPkgPrefixes , pool), procedimiento); } /* obtengo el datasource de un fichero de configuracion. esto funciona correctamente */ public static DataSource givemeDatasource (String InitialContextFactory, String providerUrl, String urlPkgPrefixes , String pool) throws Exception { Properties prop = new Properties(); prop.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY,InitialContextFactory); prop.setProperty(InitialContext.PROVIDER_URL, providerUrl); prop.setProperty(InitialContext.URL_PKG_PREFIXES,urlPkgPrefixes); //Creamos un contexto y accedemos al recurso. InitialContext ic = new InitialContext(prop); DataSource ds = (DataSource)ic.lookup(pool); return ds; }// fin método obtenerConexion. public abstract void definition (); public abstract Map execute(Object[] objeto); } ------------------------------------------------------------------------- ------------------------------------------------------------------------- Example.java ------------ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import oracle.jdbc.OracleTypes; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import es.indra.isia.PL.ProcedimientoGenerico; public class Example extends GenericProced{ private static final String name_proce = "PACKAGE1.myprocedure "; private static final String name = "name"; private static final String result = "result"; public Example(String InitialContextFactory, String providerUrl, String urlPkgPrefixes , String pool) throws Exception{ super(InitialContextFactory, providerUrl, urlPkgPrefixes , pool, name_proce); setFunction(false); //Lo pongo a false, porque es un PROCEDIMIENTO lo que estoy llamando declareParameter(new SqlParameter(name, OracleTypes.VARCHAR)); declareParameter(new SqlOutParameter("result", OracleTypes.CURSOR, new RowMapper(){ public Object mapRow(ResultSet rs, int rowNum) throws SQLException { MyEntity entity = new MyEntity( rs.getString("id"), rs.getString("name"), rs.getString("email") ); return entity; } })); compile(); } public Map execute(Object[] theObject) { Map datas = new HashMap(); datas.put(name, (String) theObject[0]); return super.execute(datas); } } ------------------------------------------------------------------------- ------------------------------------------------------------------------- Mi clase RowMapper, MyEntity.java: ---------------------------------- public class MyEntity{ private String id; private String name; private String email; public MyEntity(String id, String name, String email) { this.id = id; this.name = name; this.email = email; } public String toString( ) { return "Employee :"+id+", "+ name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this. email = email; } } ------------------------------------------------------------------------- ------------------------------------------------------------------------- Test_Example.java ----------------- import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.xml.transform.TransformerException; import Example; public class Test_Example{ public static void main(String[] args){ try{ Test_Example test = new Test_Example(); test.inicioDePrueba("Tom"); }catch (Exception e){ e.printStackTrace(); System.out.println("ERRORRR: "+e); } } public void inicioDePrueba(String name) throws TransformerException, Exception{ Example proc = new Example("org.jnp.interfaces.NamingContextFactory", "jnp://xxx.xxx.xxx.xxx:xxxx", "org.jboss.naming:org.jnp.interfaces", "NPS_POOL_NODE"); // RUN Object[] objects = new Object[1]; objects[0] = name; Map resp = proc.execute(objects); Object obj = (Object)resultado.get("result"); } } ------------------------------------------------------------------------- Cuando hago debug con el Eclipse, al ejecutar la línea Map resp= proc.execute(objects); se ejecuta sin fallo, pero la variable resp tiene el siguiente aspecto: (se supone que el mñetodo execute debe darme un Map, y lo hace, pero el objeto que me devuelve es de tipo $Proxy3. tengo entendido que es un tipo de dato que usa Sprig para encapsular objetos, pero ¿cómo puedo ibtener mi tipo de dato de forma que pueda procesarlo?) name...............................value resp...............................HashMap (id=16) ....[0]............................HashMap$Entry (id=43) ........key........................"result" ........value......................$proxy3 (id=47) el Objeto $Proxy3, ¿Cómo puedo leerlo? Muchas gracias.