Postgres中的GeneratedValue

时间:2012-10-28 08:50:36

标签: java hibernate postgresql sequence

我的实体类映射如下:

@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;
        (...)

我创建了干净的新数据库和属性:

  

< prop key =“hibernate.hbm2ddl.auto”> create< /丙>

为什么地狱(对不起,差不多两天浪费在这个bug上)创建数据库后,我在postgres数据库中得到了一个序列?:

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

我不想要一个序列,我想只是自动增加自动生成的值..

2 个答案:

答案 0 :(得分:21)

在PostgreSQL中,使用SERIAL伪类型处理自动增量。执行CREATE TABLE时使用此类型。

现在到了这一点 - 这个SERIAL伪类型创建了一个序列。 使用创建的序列处理PostgreSQL中的自动增量。 id列的默认值为 - nextval('your_sequence_name')

在Hibernate中为User实体:

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

请阅读:

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

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

答案 1 :(得分:16)

我认为Petar接受的答案不正确,或者不再正确。 Postgres中的自动增量是通过SERIAL伪类型处理的,这是正确的。但是,Petar给出的映射将导致Hibernate 5.1生成以下DDL:

CREATE SEQUENCE users_id_seq START 1 INCREMENT 50;

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

这不是使用SERIAL,而是使用Hibernate管理的序列。它不归表所有,也没有设置默认值。当然,DDL生成是许多人在生产中不使用的功能(但许多人将生成的代码作为模板)。

如果您手写DDL并实际使用SERIAL,那么使用GenerationType.SEQUENCE甚至可能与数据库行为冲突。使用Postgres的首选ID策略映射Hibernate的正确方法是使用GenerationType.IDENTITY。顺便提一下,代码也更短,更易读:

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