persistence@glassfish.java.net

Re: How does GenerationType.SEQUENCE work?

From: Quintin Beukes <quintin_at_last.za.net>
Date: Tue, 5 Aug 2008 17:01:06 +0200

Hey,

Exactly which version was this support added? Or better yet... where can I
download a latest version which can easily replace the one in Glassfish v2?

Quintin

On Tue, Aug 5, 2008 at 4:52 PM, Andrei Ilitchev <andrei.ilitchev_at_oracle.com>
wrote:

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


-- 
Quintin Beukes