web-dev-qa-db-ja.com

JPA主キーの自動生成

私の主キーエンティティは以下のようになります

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

実行するとエラーが発生する

次の値を取得または更新できませんでした。ネストされた例外はorg.hibernate.exception.SQLGrammerExceptionです。次の値を取得または更新できませんでした

しかし、私がただ変わるとき

@GeneratedValue 
private Long id;

エラーは発生しません。 Oracle dbのテーブルごとに一意の主キーを生成したい。

16
cometta

@GeneratedValue(strategy=GenerationType.TABLE)は、新しく作成されたエンティティをデータベースに挿入するときに、テーブルを使用してIDを取得するようにJPAプロバイダーに指示します。

Hibernateをプロバイダーとして使用すると、エンティティ名とこのエンティティに既に割り当てられている最大IDの2つの列を持つテーブルhibernate_sequencesが生成されます。ここでは、Hibernateがエンティティから次のIDを取得できなかったようですが、十分な情報を提供しなかったため、その理由を正確に説明することは困難です。

では、完全なスタックトレースを提供していただけませんか?また、hibernate.show_sqlプロパティをtrueに設定してロギングをオンにし、適切なログレベルlog4j.logger.org.hibernate.SQL=DEBUGを設定してください。可能であれば、ログを質問に追加してください。

Oracleの正しいhibernate.dialectが構成されていることを確認してください。実際には、可能であれば休止状態の構成にも参加してください。

PS:OracleでPKを生成する「従来の」方法は、シーケンスを使用することです(GenerationType.AUTOを使用してHibernateにデータベースタイプの最適な戦略を推測させるか、SEQUENCEを使用して強制することができます)が、結果のデータ構造がデータベースにとらわれないようにしたいとします。そうでない場合は、代わりにシーケンスを使用することをお勧めします。

編集:GenerationType.AUTOに関するOPからのコメントへの回答。実際、デフォルトはhibernate_sequenceと呼ばれる単一のグローバルシーケンスであり、これが問題になる可能性があります。ただし、以下に示す設定では、GenerationType.AUTOを使用し、データベースがシーケンスを使用する場合のシーケンスの名前を制御できます。

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private long id;

つまり、移植性を失うことなく、テーブルごとに異なるシーケンス名を使用できます。

29
Pascal Thivent

JPAでの自動生成には4つの戦略があります。

  • 自動
  • 身元
  • シーケンス
  • テーブル

Oracle自動生成主キーアノテーションの場合、シーケンスとテーブルを選択できます。基本的なロジックは、最初にジェネレータを定義することです。@ SequenceGeneratorまたは@ TableGeneratorそれぞれ、@ GeneratedValueの属性としてジェネレータを使用します。

これは、シーケンス戦略の使用方法のサンプルです。

  @Id
  @SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN")
  private long id;

以下は、テーブル戦略の使用例です。

  @Id
  @TableGenerator(name="TABLE_GEN",table="T_GENERATOR", pkColumnName = "GEN_KEY", pkColumnValue = "MONITOR2012.T_JUST_FOR_TEST", valueColumnName = "GEN_VALUE", initialValue = 1, allocationSize = 1 )
  @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLE_GEN")
  private long id;

@ GeneratedValueアノテーションでジェネレーターが指定されていない場合、選択はJPA実装に任されます。

既存のテーブルを使用してデータベースで作業している場合は、アプリケーションを実行する前に、シーケンスまたはデータベースで定義されているテーブルを確認してください。 @ GeneratedValueアノテーションが適切に機能する前に、テーブルジェネレーターもテーブルに行を挿入する必要があります

これは JPAでOracleデータベースの主キー自動生成を設定する方法 に関するチュートリアルです。

9
Sheng.W