users@glassfish.java.net

How does GenerationType.SEQUENCE work?

From: Q Beukes <java.net_at_add.za.net>
Date: Sun, 3 Aug 2008 23:48:13 +0200

Hey,

I have an entity which is basically like this:
@Entity
@Table(name = "companies")
public class Company implements Serializable
{
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"companies_SEQ")
   @SequenceGenerator(name = "companies_SEQ", sequenceName =
"companies_id_seq", allocationSize = 1)
   @Column(name = "id", nullable = false)
   private Integer id;

   //..code follows..//
}

Then I have a sequence companies_id_seq, and the table has
nextval('companies_id_seq') as a default (though this is irrelevant).

It's hosted on a PostgreSQL database, as most could probably figure out by now.

Eitherway, this only works an only with Toplink if I replace the
generator with a TABLE or AUTO generator (and in the AUTO case using
@TableGenerator, which makes both the same thing). Any other
configuration doesn't work. So I figured I'd query the SEQUENCE
problem as it's reproduceably with a default Glassfish installation.

My problem comes in at persisting the entity. It's successfully
inserted into the database, with a proper value generated for it. But
immediately after persisting, if I fetch the "id" field for the entity
it's NULL. If I make it an "int" or "long" it doesn't make a
difference... it's always NULL with object types, and 0 with basic
data types (int/long).

When I let either toplink or Postgres or OpenJPA dump the SQL, I can
see that the sequence value is queried.
It's as follows with toplink:
2008-08-03 23:04:16 SAST LOG: execute S_1: BEGIN
2008-08-03 23:04:16 SAST LOG: execute <unnamed>: INSERT INTO
vds.companies (description) VALUES ($1)
2008-08-03 23:04:16 SAST DETAIL: parameters: $1 = 'TestInsertstep2'
2008-08-03 23:04:16 SAST LOG: execute <unnamed>: select
currval('vds.companies_id_seq')
2008-08-03 23:04:16 SAST LOG: execute S_2: COMMIT

As you can see the sequence value is queried.

With OpenJPA as follows:
2008-08-03 23:35:51 SAST LOG: execute S_1: BEGIN
2008-08-03 23:35:51 SAST LOG: execute <unnamed>: SELECT
NEXTVAL('companies_id_seq')
2008-08-03 23:35:51 SAST LOG: execute S_2: COMMIT
2008-08-03 23:35:51 SAST LOG: execute S_1: BEGIN
2008-08-03 23:35:51 SAST LOG: execute <unnamed>: INSERT INTO
companies (id, description) VALUES ($1, $2)
2008-08-03 23:35:51 SAST DETAIL: parameters: $1 = '28', $2 =
'testCompany10001step2'
2008-08-03 23:35:51 SAST LOG: execute S_2: COMMIT

With both APIs the sequence value is read, and it's proved that
OpenJPA carries it at some point, though NEITHER sets it on the
entity. WHY is this? And WHY does both suffer from the same problem?

Is it a SPEC limitation? Am I doing something wrong?

Any advice would be greatly appreciated. This problem is urgent, and
has caused me many hours of grief. Thanks in advance for any/all help.

-- 
Quintin Beukes