2017-06-25 5 views
0

私は、エンティティで、次のID説明があります。このIDを生成するためのLiquiBaseを+ Postgresqlの+春JPA:Idを自動インクリメント問題

@Id 
@GeneratedValue(strategy= GenerationType.IDENTITY) 
private Long 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なしで新しいレコードを挿入しようとすると、問題が発生しました。 "duplicate id"のようなメッセージでエラーが発生しました。 したがって、jpa(hibernate)は新しいid値を取得するためにpostgresqlシーケンスを使用しないことを理解しています。また、エンティティのID記述にシーケンス名を含めることは望ましくありません。私はこの状況がpostgresql自体によって解決されることを期待しています。 そして、私は 'hibernate_sequence'を使用しません。 だから、どのように私はこの問題を解決することができます任意のアイデア。 ありがとうございます。

+0

FYI PostgreSQLのJPA GenerationType.IDENTITYは、 "SERIAL"カラムタイプ(つまり、データストアで生成された)を使用することを意味します。これはSEQUENCEではありません。 SEQUENCEを望むなら、私はJPAの 'GenerationType.SEQUENCE' –

+0

を使っていたでしょうが、liquibaseは 'serial'型を生成しません。 –

+0

JPAとLiquibaseの両方を使いたい場合、JPAでIDENTITYを使うことはできません。 –

答えて

3

Liquibaseの指示autoIncrement="true"は、PostgreSQL用にserialカラムを生成します。 serialカラムの場合、PostgreSQLはtablename_colname_seqのような名前のシーケンスを作成します。この列からデフォルトの列値が割り当てられます。

明示的にの値をシリアル列に挿入すると、シーケンスジェネレータには影響せず、次の値は変更されません。したがって、重複した値が生成される可能性があります。あなたが明示的な値を挿入した後

はこれを防ぐために、あなたはこの問題を修正する必要があり

ALTER SEQUENCE tablename_colname_seq RESTART WITH 42; 

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

:例えば、ALTER SEQUENCE文でまたはsetval()機能のいずれかでシーケンスジェネレータの現在の値を変更する必要があります。

関連する問題