2010-12-03 8 views
1

期待通りHibernateはバッチ操作機能していない私はPersonクラスを持っていますヌル。次fields-</p> <blockquote> <p>ID、hashedId、説明</p> </blockquote> <p>idは、シーケンスによって生成された主キーであり、hashedIdがされていないと

私は、次の手順を実行します

  1. session.saveOrUpdate(人)
  2. person.setHashedId(ハッシュ(person.getId()))

IdがありますDBで自動生成されます。私はこれを行うと、はずの私が唯一の2文

  1. を期待して選択し、次のシーケンスID(人物ID)を取得する
  2. 挿入人物のレコードを挿入するには?

しかし、それはヌルhashedIdで(最終トランザクション中ofcourseの、コミット)右のステップ1の後に挿入しようとしている - 私は戻って、制約違反エラーを取得する - HashedIdはnullにすることはできません。

答えて

1

Hibernateは:-) http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-idを参照してください。正しいことをやっている、セクション「5.1.4.4。ID列とシーケンス」Hibernateがない、それがDBによって生成されます場合はIDを知っているためだ

。そして、IDは実際にあなたがシーケンスを呼び出しただけでレコードに割り当てられません。したがって、Hibernateにレコードを保存させ、レコードの実際のIDを取得させるか、Hibernateが生成したID(hiloなど)を使用する必要があります(または、ジェネレータタイプが "assigned"の自分で生成する)。

2

Session.save()などと呼んだ場合、HibernateはただちにIDを生成し、後で保存するために単にキューに入れるのではなく、挿入を行います。したがって、要素が挿入される前にそのIDが割り当てられているギャップはありません。 「ID」ID生成戦略のために、とにかくこれらを分割することは全く不可能です。

私の経験では、この種のケースを処理する最も安全かつ簡単な方法は、インターセプタ(または多分EventListener? )hashedIdプロパティが設定されていない状態で挿入されているエンティティをトラップし、セーブ直前に生成します。少し不愉快ですが、IMHOはID生成をアプリケーションコードに引き込むよりも優れています。

は、ここで私は(インターセプタを使用して)新しいチケットエンティティの「参照」プロパティを生成する例を示します

public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, 
    Type[] types) { 
    boolean changed = super.onSave(entity, id, state, propertyNames, types); 

    if (entity instanceof Ticket) { 
     for (int i = 0; i < propertyNames.length; i++) { 
      if (propertyNames[i].equals("reference") && state[i] == null) { 
       state[i] = generateTicketReference((Integer) id); 
       changed = true; 
      } 
     } 
    } 

    return changed; 
} 
0

HashedIdフィールドは右、IDから派生していますか?安価な機能に基づいて、私は思いますか?だからこの場合、あなたは本当にそのフィールドをDBに保持する必要がありますか?クエリで直接使用していますか? getHashId()メソッドは常にハッシュ(this.id)を返すことはできませんか?この方法では、データベースにhashedIdフィールドがなく、管理する必要はありません。単純にidに基づいて推測されます。

これが役に立ちます。

関連する問題

 関連する問題