web-dev-qa-db-ja.com

@GeneratedValue withstrategy = GenerationType.AUTOは、再起動後に繰り返し値を生成します

IDが次のように構成されたHibernateエンティティがあります

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

新しい要素の作成は、最初の実行で問題なく機能します。しかし、アプリケーションを再起動してレコードを取得し直すと、次にこのエンティティを永続化しようとすると、hibernateはアプリケーションが再起動されなかったときに生成されたものと同じIDを使用しようとします。

以下のエラーが発生し、トレースオプションを指定して実行すると、IDが再利用されていることがわかりました。

* Hibernate:org_myEntity(entitiyJID、entitityName、id)の値(?、?、?)に挿入org.hibernate.util.JDBCExceptionReporter
SQLエラー:20000、SQLState:23505 org.hibernate.util.JDBCExceptionReporterで定義された「SQL120725164357680」で識別される一意または主キーの制約または一意のインデックスで重複キー値が発生したため、ステートメントが中止されました'TABLE_NAME'。 org.hibernate.event.def.AbstractFlushingEventListener
データベースの状態をセッションorg.hibernate.exception.ConstraintViolationExceptionと同期できませんでした:できませんでした*

ちなみに、私はhibernate 3.3.2.GA、javax.persistance 2.0.0、Derby10.5.1データベースを使用しています

誰かが私の世代で何が間違っている可能性があるのか​​、そしてどうすればそれを修正できるのか考えていますか?

10
Thomas

AUTOを使用する場合、HibernateはIDを生成するための戦略の1つを選択します。参照から:

AUTO-基になるDBに応じて、ID列、シーケンス、またはテーブルのいずれか。

したがって、ダービーが使用している戦略を確認するには、生成されているIDを確認する必要があります。見た目はそうですが、アプリを再起動するたびにジェネレーターがリセットされます。設定してみてください

<prop key="hibernate.hbm2ddl.auto">update</prop>

ただし、シーケンスジェネレータを使用してすばやく修正できます。お気に入り:

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="ENTITY_SEQ")
private Long id;

ここで、ENTITY_SEQは、データベース内のシーケンスの名前です(手動で作成します)。

14
Tiago Farias