私は永続化レイヤーとしてJPA(Hibernate)を使用するSpringブートアプリケーションを開発中です。既存のデータを一括して挿入する:すべての挿入の前にJPAがselectを実行するのを防ぐ
現在、移行機能を実装しています。基本的には、システムのすべての既存のエンティティをXMLファイルにダンプします。このエクスポートにはエンティティのIDも含まれます。
私が抱えている問題は、反対側にあり、既存のデータを再インポートしています。このステップでは、XMLは再びJavaオブジェクトに変換され、データベースに永続化されます。
エンティティを保存しようとすると、EntityManager
クラスのmerge
メソッドが使用されています。すべて正常に保存されます。
ただし、Hibernateのクエリログを有効にすると、すべての挿入クエリの前に、選択クエリが実行され、そのIDを持つエンティティが既に存在するかどうかが確認されます。これは、エンティティがすでに提供しているIDを持っているためです。
私はこの動作を理解しており、実際には意味があります。しかし、IDは存在しないので、選択が私の場合に意味をなさないと確信しています。何千ものレコードを節約しているので、大規模なテーブルで何千もの選択クエリが発生し、インポートプロセスが大幅に遅くなっています。
私の質問:「挿入する前にエンティティが存在するかどうかのチェック」をオフにする方法はありますか?
追加情報:
を持続org.hibernate.PersistentObjectException:
私が代わりにマージの
entityManager.persist()
を使用し、私はこの例外を取得 に渡さ切り離さエンティティが
提供された/提供されたIDを使用できるようにするには、私はこのIDジェネレータを使用します:
@Id
@GeneratedValue(generator = "use-id-or-generate")
@GenericGenerator(name = "use-id-or-generate", strategy = "be.stackoverflowexample.core.domain.UseIdOrGenerate")
@JsonIgnore
private String id;
発電機自体:
public class UseIdOrGenerate extends UUIDGenerator {
private String entityName;
@Override
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
entityName = params.getProperty(ENTITY_NAME);
super.configure(type, params, serviceRegistry);
}
@Override
public Serializable generate(SessionImplementor session, Object object)
{
Serializable id = session
.getEntityPersister(entityName, object)
.getIdentifier(object, session);
if (id == null) {
return super.generate(session, object);
} else {
return id;
}
}
}
ありがとう、私はそれを言及するのを忘れました。私はpersistを使用しようとしましたが、例外がスローされます。オリジナルの投稿に詳細を更新しました。 – geoffreydv
あなたが変更することができる場合は、私のアップアップを確認してください –
それは良いアイデアですが、私は正しく理解すると、IDは空であるため、アプリケーションの他の部分に新しい項目を挿入することができなくなります。私は手動でsetId(generateId())をどこでも実行する必要がありますが、これは現在オプションではありません。 – geoffreydv