2016-05-29 27 views
5

私は、HibernateとJava EEを使用して私のpostgresqlに新しいレコードを挿入しようとしています。ここHibernate:重複キー値が一意制約に違反しています

@Entity 
@SuppressWarnings("serial") 
@Inheritance(strategy=InheritanceType.JOINED) 
public class BaseDesign implements Serializable { 

    @Id 
    @Expose 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", updatable = false, nullable = false) 
    private Long id; 

    @Version 
    @Column(name = "version") 
    private int version; 

    @Expose 
    @Column(name = "name") 
    private String name; 

    // getter and setter 
} 

そして、私のimport.sql

INSERT INTO basedesign (id, name, version) VALUES (1, 'China', 0); 

私はコードをビルドする場合、レコードはDBに追加されている。

は、これは私のモデルです。

しかし

、私はこのようなEntityManagerを使用して、新しいレコードを追加しよう:

BaseDesign design = new BaseDesign(); 
design.setName("USA");     
em.persist(design); 

は、私が得た:

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "basedesign_pkey" 
    Detail: Key (id)=(1) already exists. 

2回目の同じコマンドを実行し、それが成功。

なぜHibernateは最初に開始IDをインクリメントしないのですか?最後に挿入された整数から開始するように設定する方法は?

答えて

7

Postgresqlでbigserialカラムを作成すると、are actually creating a sequenceとなります。 ID値 '1'を手動で挿入すると、PostgreSQLはこれを考慮してシーケンスを更新しませんでした。 HibernateはPostgresqlにシーケンスを使ってIDを生成させますが、生成される最初の値は '1'です。これは衝突します。 2番目の値は正常です。

あなたが休止状態の後ろに行くと、直接SQLを使用して問題を作成した場合、あなたはそれを同じように修正する必要があります:use ALTER SEQUENCE to set the next valueは:

alter sequence basedesign_id_seq restart with 2; 
+0

だから、このソリューションは、それまで知られている番号を割り当てる必要がありますか?最後のIDを自動的にピックアップできませんか? – VHanded

+1

問題は、手動でIDを挿入したSQL挿入ステートメントです。システムは自動的にIDを取得することができます。ただし、システムがIDを生成し、idカラムの値を決して提供しないようにすることは常に可能です。 –

+0

ありがとうございます。私が達成しようとしているのは、バックアップとリストアです。私はDBからダンプファイルを生成するとき、それにIDを持つINSERT文が付属しています。そのIDはDBによって生成されないため、上記の問題が発生しました。 – VHanded

関連する問題