Liquibase + Postgresql + Spring Jpa:Id自动增量问题

时间:2017-06-25 07:51:40

标签: java postgresql hibernate jpa liquibase

我在实体中有以下Id描述:

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

用于生成此ID的Liquibase指令如下:

  <column name="id" autoIncrement="true"  type="INT">
     <constraints nullable="false" primaryKey="true" primaryKeyName="pk_entity"/>
  </column>

此外,我还有liquibase脚本,可以在此表中插入预定义的值,例如

    <insert tableName="entityTable" schemaName="public">
        <column name="id">1</column>    
        <!- other fields-->
    </insert>

当我尝试使用Jpa存储库插入没有id的新记录时出现问题。 我收到一条错误消息,例如&#34;重复ID&#34;。 所以,据我所知,jpa(hibernate)并没有使用postgresql序列来获取新的id值。我不想将序列名称包含在实体的ID描述中。我希望postgresql本身可以解决这种情况。 而且我不会使用&#39; hibernate_sequence&#39;。 所以,任何想法如何解决这个问题。 谢谢。

2 个答案:

答案 0 :(得分:5)

Liquibase的指令autoIncrement="true"为PostgreSQL生成serial列。对于serial列,PostgreSQL将创建一个名称为tablename_colname_seq的序列。将从此序列中分配默认列值。

但是当显式地将值插入到串行列中时,它不会影响序列生成器,并且它的下一个值不会改变。因此它可以生成重复值,这正是您的情况。

要在插入显式值后阻止此操作,您需要使用ALTER SEQUENCE语句或setval()函数更改序列生成器的当前值,例如:

ALTER SEQUENCE tablename_colname_seq RESTART WITH 42;

SELECT setval('tablename_colname_seq', (SELECT max(colname) FROM tablename));

这应解决问题。

答案 1 :(得分:0)

首先创建表名称的示例:

CREATE TABLE TABLE_NAME(ID_NAME SERIAL PRIMARY KEY NOT NULL);

然后在您的注释中:

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