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

Art*_*tau 2 java postgresql hibernate jpa liquibase

我在实体中有以下ID说明:

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
Run Code Online (Sandbox Code Playgroud)

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

  <column name="id" autoIncrement="true"  type="INT">
     <constraints nullable="false" primaryKey="true" primaryKeyName="pk_entity"/>
  </column>
Run Code Online (Sandbox Code Playgroud)

我也有liquibase脚本,可以将预定义值插入该表,例如

    <insert tableName="entityTable" schemaName="public">
        <column name="id">1</column>    
        <!- other fields-->
    </insert>
Run Code Online (Sandbox Code Playgroud)

当我尝试使用Jpa存储库插入没有ID的新记录时出现了问题。我收到类似“重复ID”的错误消息。因此,我知道jpa(hibernate)不使用postgresql序列来获取新的id值。而且我不想在实体的ID描述中包含序列名称。我希望Postgresql可以解决这种情况。而且我不会使用“ hibernate_sequence”。因此,任何想法我都可以解决此问题。谢谢。

小智 6

Liquibase的指令为PostgreSQL autoIncrement="true"生成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));
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题。