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データベースを使用しています
誰かが私の世代で何が間違っている可能性があるのか、そしてどうすればそれを修正できるのか考えていますか?
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は、データベース内のシーケンスの名前です(手動で作成します)。