0

これをここに投稿する前にウェブで検索しましたが、重要なプロジェクトに参加していて、これ以上無駄にする時間がありません。さて、これが取引です:

データベース ( SqlServer )内の私のテーブルは、Hibernateによって自動的に作成されます。したがって、エンティティがあり、このエンティティは以前に Id アノテーションでマップされていました。

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

Hibernate はテーブルdbo.ParcelaをsqlServer内に作成しましたが、ID を生成する方法を変更する必要がありました。これは、ID 番号を受け取り、その ID をデータベースに保存したい場合があるためです。したがって、エンティティは次のようになります。

@Id
private Integer id;

プログラムを初めて実行するときは問題なく動作しますが、古い Id マッピングを使用してデータベースを既に作成している顧客がいて、新しい Id マッピングを使用して新しいテーブルを作成することはできません。したがって、新しいレコードを挿入しようとすると、次のメッセージが表示されます。

SEVERE: Cannot insert explicit value for identity column
in table 'Parcela' when IDENTITY_INSERT is set to OFF.

どんな助けでも感謝します。

ありがとう

4

2 に答える 2

1

そのため、代理キーが顧客によって既に生成されている場合を除き、データベースによって生成される代理キーが必要です。データベースが id=12345 を設定しようとしているが、その ID を持つ顧客がインポートしたエントリが既に存在する場合、どのように衝突を回避しますか?

あなたの質問に対する簡単な答えは、「これをしないでください」です。古い自然キーと代理キーの議論には入りたくありません。これは、たとえばここで既に行われています。そして、「codd代理キー」をグーグルで検索して、それらを適切に使用する方法を学びます。私が言いたいのは、代理キーを使用する場合は、データベースに代理キーを生成させ、外部からのすべてを追加の検索キーとして扱うことです。それは正気の方法です。

長い答えは次のとおりです。本当にこれを行いたい場合、および自分が何をしているのかを本当に理解している場合は、独自の IdGenerator クラスを実装できます。たとえば JPA では、ID にアノテーションを付けることができます。

@Id
@GenericGenerator(name = "customId", strategy = "com.example.CustomIdGenerator", parameters = { @Parameter(name = "sequence", value = "SEQ_IDGENERATOR") })
@GeneratedValue(generator = "customId")
@Column(name = "ID", unique = true, nullable = false)
private Integer id;

次に、customIdGenerator は SequenceGenerator を拡張します。

public class CustomIdGenerator extends SequenceGenerator {

  public Serializable generate(SessionImplementor session, Object obj) {
    // return o.getId() if obj.getId() is not null
    // newId = SEQ_IDGENERATOR.nextval
    // while (newId is already in db) newId = SEQ_IDGENERATOR.nextval
    // return newId
  }
}

データベースは SEQ_IDGENERATOR を提供します。Id は自動生成されたフィールドではなくなり、単純に

create table foo( id integer not null primary key, ...);

しかし、繰り返しますが、これはしたくありません。代理キーを外部の世界とは無関係にし、データベースで処理する必要があります。

于 2012-11-22T15:35:49.760 に答える
0

HibernateにDBのスキーマをどのように作成させましたか?hbm2ddlを使用した場合は、おそらく追加します

<property name="hibernate.hbm2ddl.auto" value="update"/>

永続性.xmlに設定hbm2ddl.autoするか"update"、Hibernateが再デプロイ時にdbスキーマを自動的に更新するように設定すると、挿入の問題が修正されます。

もちろん、既存のIDを挿入しようとした場合には役に立ちませんが、ご存知だと思います:)

于 2012-11-22T12:11:56.907 に答える