Quando usiamo Postgresql, utilizziamo i campi di tipo serial
come primary key.
Ogni volta che viene poi creata una entità sul database viene recuperato l'id generato e settato sull'oggetto che la rappresenta.
Di seguito il codice che fa' questa cosa:
< ... omissis codice della insert ... >
i = 1;
// Con questa stored cerchiamo di leggere il nome del seriale da invocare
ps = conn.prepareStatement("select pg_get_serial_sequence(?, ?)");
ps.setString(i++, "public.socio");
ps.setString(i++, "id");
ResultSet rs = ps.executeQuery();
String sequenceName = "";
if (rs.next())
sequenceName = rs.getString(1);
i = 1;
// Con questa chiamata chiediamo al seriale l'id generato per l'oggetto appena creato;
// lo settiamo sull'entita' e lo ritorniamo.
ps = conn.prepareStatement("select currval(?)");
ps.setString(i++, sequenceName);
rs = ps.executeQuery();
if (rs.next())
bean.setId(rs.getInt(1));
else
throw new SQLException("Errore nel retrive del currval dalla tabella");
Capita a volte, però, per mille motivi, che la chiamata alla stored 'pg_get_serial_sequence
' non ritorni correttamente il nome del seriale.
Per sistemare la cosa basta "insegnare" al database quale seriale usare per una data colonna, in questo modo:
1) guardare, dalla shell di postgres, qual'e' il seriale che si ha sulla tabella per la chiave primaria interessata
myDb=# \d socio
Table "public.socio"
Column | Type | Modifiers
--------------+---------+-----------------------------------------------------
id | integer | not null default nextval('socio_id_seq1'::regclass)
...
In questo caso, il seriale è 'socio_id_seq1
'.
2) istruire Postgresql perchè sappia che il seriale per quella tabella è quello che vogliamo noi:
alter sequence socio_id_seq1 owned by socio.id;
dove:
- socio_id_seq1 è il nome del seriale
- socio.id è la tabella.campo della chiave primaria
Ed il gioco è fatto! :)