2016-08-17 11 views
2

挿入すると正常に主キーIDを生成するために:私は、アプリケーションを起動したときにHibernateを使用してデータベースにどのように自動Hibernateは私が主キーに定義されたとしてメンバーのエンティティクラス持つレコード

@Id 
    @GeneratedValue 
    private Long id; 

Iあらかじめロードされた2つのレコード:+ ---- + ------

select * from Member; 
+----+---------------------------+------------+--------------+ 
| id | email      | name  | phone_number | 
+----+---------------------------+------------+--------------+ 
| 0 | [email protected] | John Smith | 2125551212 | 
| 1 | [email protected] | Mary Smith | 2025551212 | 

insert into Member (id, name, email, phone_number) values (0, 'John Smith', '[email protected]', '2125551212') 
insert into Member (id, name, email, phone_number) values (1, 'Mary Smith', '[email protected]', '2025551212') 

今MySQLデータベースには二つのレコードを持っています--------------------- + ------------ + -------------- +

は今、私の会員登録ページ、私は新しいメンバーを登録するための要求を送信したとき、私はこのエラーメッセージ受信中:

Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY' 

を私はそれが自動生成されたキーは常に 'で始まるので、それを考え出しました1 'が、データベースにはすでに2つのレコードがあるため、主キー' 1 'は重複しています。

私の質問は、テーブル内にいくつかの既存のレコードがあれば、プライマリキーを正しく作成する方法です。私は

@GeneratedValue 

アノテーションを使用しない場合は、私はいつも挿入する前に、データベーステーブルから次のキーは何を見つける必要があります。

この状況を処理する最も良い方法はありますか?

EDITED: 示唆したように、私はStragey使用:奇妙な何

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

すると、2つの既存のレコードは以下のように表に存在する場合、ということです。

select * from English; 
+----+------------+---------+--------+ 
| id | sentence | source | status | 
+----+------------+---------+--------+ 
| 1 | i love you | unknown |  0 | 
| 2 | i like you | unknown |  0 | 
+----+------------+---------+--------+ 

私が登録した後テーブルに新しいレコードがある場合、新しいIDは、以下のように3ではなく4で始まります。

select * from English; 
+----+----------------+---------+--------+ 
| id | sentence  | source | status | 
+----+----------------+---------+--------+ 
| 1 | i love you  | unknown |  0 | 
| 2 | i like you  | unknown |  0 | 
| 4 | I have a book. | Unknown |  0 | 
+----+----------------+---------+--------+ 
3 rows in set (0.00 sec) 

これはどうしてですか?

+0

保存に使用するテーブルスキーマとコードを提供する必要があります。一般に、あなたは*何もしないで保存します。これがラッパー型としてのポイントです。 – chrylis

+0

挿入ステートメントにIDを入力しないでください。 – Jens

答えて

3

発電機IDENTITYを使用する必要があります。 IDENTITYジェネレータを使用すると、integerおよびbigintカラムをオンデマンドで自動インクリメントできます。増分プロセスは、より重いトランザクションコースグレインロックとは対照的に、データベースの内部軽量ロックメカニズムを使用するため、非常に効率的です。

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

また、自動的に生成されるため、insert文でidを使用しないでください。

@GeneratedValue(strategy=GenerationType.AUTO) 

=>指定:SEQUENCEは、MySQL用のMySQL

+0

私は試してみます。ありがとう。 – user697911

+0

"オンデマンドで自動インクリメント"とは、テーブルにすでに2つのレコード "1"と "2"がある場合、1ではなく新しいプライマリキー "3"が生成されることを意味します。 – user697911

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

とし、それを維持する場合はnull (0)のままにしてください。

は、いくつかのケースではAUTO戦略がSEQUENCEにではなく、IDENTITYまたはTABLEに解決されるので、手動で(基礎となるデータベースによって異なります)IDENTITYまたはTABLEに設定することをお勧めします。

あなたのために働くシーケンス名を指定するのは、SEQUENCE +と思われます。

0

では動作しないよう
なおSEQUENCEがあなたのために動作しません、あなたは成功した下記の戦略のいずれかを使用して持続することができるでしょう主キー

@GeneratedValue(strategy=GenerationType.IDENTITY) 

=>プライマリキー

ためAUTO_INCREMENT属性を指定するためのAUTO_INCREMENT属性native:さらに高度な使用方法では、あなたが別のテーブルの主キーを指定することができますTABLE戦略GenerationType.TABLEを利用することができますし、あなたが@TableGenerator

としてこのテーブルを指定することができますHibernateはまた、生成戦略を持っています。基礎となるデータベースの能力に基づいて生成戦略を適切に選択します。

0
<id name="id" column="id" type="integer"> 
    <generator class="increment"></generator> 
</id> 

マッピングクラスを使用している場合は、上記のコードを使用してプライマリキーを自動的に生成してください。

あなたはデシベルは最後にこれを追加移入スクリプトで
0

(PostgreSQLの):13 WITH

ALTER SEQUENCE RESTART。配列名、たとえば見つけるためデシベルで

表情:13 WITH

ALTER SEQUENCE role_role_id_seq RESTARTを。

あなたがモデル上の注釈と同様に生成された系列名に名前を付けることができるはず...

はそれが役に立てば幸い!

関連する問題