Trabajando en mi proyecto de título, me tope con un problema. Contextualizando un poco el problema:

  • una tabla con un campo serial (autogenerado).
  • una tabla que necesita como llave foranea, el campo serial anterior
  • para ingresar valores a las tablas anteriores, ambas se hacen a través de funciones de postgres.
  • jdbc de postgres
  • La interfaz de jdbc provee el método getGeneratedKeys() que debiera entregar un ResultSet, con todos las llaves que se crearon. Después de un (buen) rato viendo que porque no funcionaba y buscar el problema en mi código dí con las primeras luces de mi problema:

  • La versión que estoy ocupando del jdbc es la última a la fecha 8.3-603 no soporta este método y lamentablemente al ejecutarlo no tira una exception gritando acerca de esto, como al parecer lo hacia en versiones anteriores.
  • Obviamente muy empantanado y sin mucho tiempo de leer la documentación recurrí a la lista en español de postgresql donde me ayudaron a reescribir la función en cuestion, quedando de la siguiente manera:


    CREATE OR REPLACE function ingresarVoucherEntrada( _idEmpleado "int4", _idProveedor "int4", _fechaEmision"date", _documentoAsociado"int4")
    returns int as $$
    insert into voucherEntrada (idEmpleado, idProveedor, fechaEmision, docuementoasociado)
    values ($1, $2, $3,$4);
    select currval(‘voucherentrada_idvoucherentrada_seq’)::int;
    $$ LANGUAGE ’sql’ VOLATILE;

    La parte en negrita es lo que hace la magia. Devuelve un entero, que es el entero que tiene la llave que me interesa recuperar. Y ¿cómo la recupero? Seleccionando el “valor actual” de la secuencia del “voucherentrada_idvoucherentrada_seq”.
    Esta última secuencia (sequence) se genera automáticamente al definir un campo como serial.
    Luego, mi método que ocupa esta función, tiene que devolver el identificador del registro que se ha creado recientemente y se lo paso como parámetro al método que llena la tabla usando el identificador de la primera tabla.

    4 Respuestas a “Postgres: getGeneratedKeys() y jdbc.”

    1. César Sepúlveda dice:

      Full pega con tú proyecto de titulo parece…

      Suerte viejo!!.

    2. César Sepúlveda dice:

      Porque aparecía mi blog como blogspot!!!??? :?

    3. felipe dice:

      hola,

      con eso funciona, pero ten ojo que eso no necesariamente deberia funcionar en un sistema con base de datos replicada :P, AFAIK deberias indicarle a postgres donde inicia y donde finaliza la transacción para que el se asegure de que sea atomica.

      no cacho de que es tu sistema, pero si lo necesitas distribuir puede ser un cacho.
      BTW, just for the record, el driver jdbc de postgres es como la reverenda corneta :D no soporta ni siquiera JPA

    4. Carolina dice:

      Jejejeje, llevo como 7 meses trabajando con Postgres y no tengo ni la más remota idea de qué hablas. Pero esto me ha dado una idea, tal vez tú sabes cuál es la mejor forma teórica de hacer una cosa. ¿Cuándo te podrás conectar un ratito para darme una idea?

    Deja una Respuesta