Cichy
Cichy

Reputation: 1329

GeneratedValue in Postgres

I have my entity class mapped like below:

@Entity
@Audited
@Table(name="messages_locale")
public class Locale {

    @Id
    @GeneratedValue
    @Getter @Setter //Project Lombok's annotations, equal to generated getter and setter method
    private int id;
        (...)

I create clean new database ,and properties:

< prop key="hibernate.hbm2ddl.auto" >create < /prop>

WHY THE HELL (Sorry, almost two days wasted on this bug) after created database, i got a sequence in my postgres db?:

CREATE SEQUENCE hibernate_sequence
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 2
  CACHE 1;
ALTER TABLE hibernate_sequence
  OWNER TO postgres;

I dont want to have a sequence, I want to have just auto increment auto generated values..

Upvotes: 13

Views: 38844

Answers (2)

Michael Piefel
Michael Piefel

Reputation: 19968

I think the accepted answer from Petar is not correct, or not correct any longer. The auto-increment in Postgres is handled through SERIAL pseudo type, that’s correct. However, the mapping that Petar gives will result in the following DDL generated by Hibernate 5.1:

CREATE SEQUENCE users_id_seq START 1 INCREMENT 50;

CREATE TABLE … (
    id INT8 NOT NULL,
    …
);

This is not using SERIAL, but a Hibernate managed sequence. It is not owned by the table and no default value has been set. Of course, DDL generation is a feature that many people do not use in production (but many take the generated code as a template).

If you hand-write your DDL and actually used SERIAL, then using GenerationType.SEQUENCE may even conflict with the database behaviour. The correct way to map Hibernate with Postgres’ preferred ID strategy is using GenerationType.IDENTITY. Incidentally, the code is also much shorter and more readable:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;

Upvotes: 29

Petar Minchev
Petar Minchev

Reputation: 47363

In PostgreSQL auto-increment is handled using the SERIAL pseudo type. You use this type when you execute CREATE TABLE.

Now to the point - this SERIAL pseudo type creates a sequence. Autoincrement in PostgreSQL is handled using the created sequence. The default value of the id column becomes - nextval('your_sequence_name').

In Hibernate for an User entity:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "users_seq_gen")
@SequenceGenerator(name = "users_seq_gen", sequenceName = "users_id_seq")
public Long getId() {
     return id;
}

Read here:

http://www.postgresql.org/docs/8.4/static/datatype-numeric.html#DATATYPE-SERIAL

http://www.neilconway.org/docs/sequences/

Upvotes: 26

Related Questions