シーケンスから設定する必要のあるNON-IDフィールドを持つエンティティがあります。現在、シーケンスの最初の値をフェッチしてクライアント側に保存し、その値から計算しています。
しかし、私はこれを行うための「より良い」方法を探しています。次のシーケンス値をフェッチする方法を実装しました。
public Long getNextKey()
{
Query query = session.createSQLQuery( "select nextval('mySequence')" );
Long key = ((BigInteger) query.uniqueResult()).longValue();
return key;
}
ただし、この方法ではパフォーマンスが大幅に低下します(〜5000オブジェクトの作成は3分の1に遅くなります-5740msから13648msになります)。
「偽の」エンティティを追加しようとしました。
@Entity
@SequenceGenerator(name = "sequence", sequenceName = "mySequence")
public class SequenceFetcher
{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence")
private long id;
public long getId() {
return id;
}
}
ただし、このアプローチも機能しませんでした(返されたIDはすべて0でした)。
誰かがHibernateを効率的に使用して次のシーケンス値をフェッチする方法を教えてもらえますか?
編集:調査の結果、 Hibernateがで記述されたシーケンスにアクセスするときにフェッチの数を減らすことができたため、呼び出しは-を使用するQuery query = session.createSQLQuery( "select nextval('mySequence')" );
よりもはるかに非効率的であることがわかりました。@GeneratedValue
@GeneratedValue
たとえば、70,000個のエンティティを作成すると(つまり、同じシーケンスから70,000個の主キーがフェッチされると)、必要なものがすべて取得されます。
ただし、Hibernateは1404 select nextval ('local_key_sequence')
コマンドのみを発行します。注:データベース側では、キャッシュは1に設定されています。
すべてのデータを手動でフェッチしようとすると、70,000回の選択が必要になるため、パフォーマンスに大きな違いが生じます。Hibernateの内部機能と、それを手動で再現する方法を知っている人はいますか?