persistence@glassfish.java.net

Re: How does GenerationType.SEQUENCE work?

From: Andrei Ilitchev <andrei.ilitchev_at_oracle.com>
Date: Tue, 5 Aug 2008 10:52:01 -0400

When you use GenerationType.TABLE the sequence value is obtained from the
sequence table, then assigned to Java object's id, then inserted into the
db.

If the table was created with SERIAL pk you should use
@GeneratedValue(strategy = GenerationType.IDENTITY) In that case the id
won't appear in Java object's id untill sql is executed, therefore to access
id before commit call em.flush();

In case the table was created without SERIAL pk you should be able to use
GenerationType.SEQUENCE on PostgreSQL - in that case (just like in TABLE
case) the sequence value is assigned to Java object before it's inserted in
the db table (so no flush would be require to access the id before commit).
Support of SEQUENCE for PostgreSQL was added around the end of 2007, before
that on PostgreSQL SEQUENCE behaved as IDENTITY, so if this case doesn't
work for you may be on an older version.

Thanks,

Andrei


----- Original Message -----
From: "Quintin Beukes" <quintin_at_last.za.net>
To: <persistence_at_glassfish.dev.java.net>
Sent: Sunday, August 03, 2008 5:59 PM
Subject: How does GenerationType.SEQUENCE work?


> 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
>