persistence@glassfish.java.net

Code changes for Issue 283 : Postgresql and SERIAL field

From: Pramod Gopinath <Pramod.Gopinath_at_Sun.COM>
Date: Thu, 23 Mar 2006 16:13:40 -0800

Hi Tom
  These code changes deal with SERIAL field of Postgresql database. The
related issue is
https://glassfish.dev.java.net/issues/show_bug.cgi?id=283.

*Problem Description :*
For an entity if the user has specified
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)

we generate a SERIAL field. For this type of field, postgresql database
creates an implicit sequence in the database. Each time a row is
inserted into this table, the next id field value would be picked from
this implicit sequence. Currently we are forcing the user to also define
the
@SequenceGenerator annotation with the correct sequence name to ensure
that our code works correctly.

*Proposed Changes :*
The code changes that I have attached deal with automatically setting
this sequence name correctly for Postgresql platform. The files affected
are :

src/java/oracle/toplink/essentials/internal/databaseaccess/DatabasePlatform.java
   Added a new method : getDBSequenceName(String tableName, String
pkFieldName) which returns null

src/java/oracle/toplink/essentials/platform/database/PostgreSQLPlatform.java
   This platform ensures that we return back a String that would be of
the form tableName_pkFieldName_seq

src/java/oracle/toplink/essentials/internal/sessions/DatabaseSessionImpl.java
   This is where the actual logic is currently placed.
   I have added a new method resetSequenceName() and the logic for this
method can be summed as :
          if it is PostgreSQLPlatform
              get a list of all the descriptors and iterate over them
                   if the descriptor.hasSimplePrimaryKey()
                        if the sequenceName is set on the descriptor and
is equal to the default sequence ("SEQ_GEN_SEQUENCE")
                        then
                                get the tableName, primaryKeyFieldName
from the descriptor
                                call into the
platform.getDBSequenceName(tableName, primaryKeyFieldName)
                                create a NativeSequence using this name
and add this native sequence into the model
                               set the sequence NAme into the descriptor
                               set a boolean flag to true.
                        endif
                   endif
             end loop
             if the flag is set to true it implies that we have atleast
one descriptor whose sequenceName was changed
                 recreate the sequence objects so that the native
sequences that we created are setup correctly
         end if
                               

Currently this method resetSequnce() has been placed in the
DatabaseSessionImpl() and is called after the call to
 initializeDescriptors() in postConnectDatasource().
Did think of having this code in PostgreSQLPlatform but was not sure if
that was the correct thing to do.
Anyway it would be great to hear your comments on the changes.

Thanks
Pramod