JPAでは、Hibernateの saveOrUpdateの動作 を複製する方法はありますか?
saveOrUpdate
public void saveOrUpdate(Object object)
throws HibernateException
Either save(Object) or update(Object) the given instance, depending upon resolution of the unsaved-value checks (see the manual for discussion of unsaved-value checking).
This operation cascades to associated instances if the association is mapped with cascade="save-update".
Parameters:
object - a transient or detached instance containing new or updated state
Throws:
HibernateException
See Also:
save(Object), update(Object)
基本的に、オブジェクトがデータベースに既に存在するかどうかを確認し、必要に応じてそのオブジェクトを更新するか、オブジェクトの新しいインスタンスを保存します。
JPA transcationless読み取りは素晴らしいですが、Hibernateからこのメソッドが本当に欠落しています。経験豊富なJPA開発者はこれをどのように処理しますか?
EntityManager.merge
メソッドを使用してみてください-これは非常に似ています。
Xebiaのブログ投稿には、優れた説明があります。「 JPA実装パターン:(デタッチされた)エンティティの保存 」
Pablojimがリンクした記事で概説されている方法の問題は、自動生成された主キーをあまりうまく処理できないことです。
新しいORMエンティティオブジェクトの作成を検討してください。データベーステーブルの既存の行と同じデータをこれに与えることができますが、間違っていない限り、エンティティマネージャは同じプライマリキーを持つまでそれらを同じ行として認識しません。 、自動生成キーを使用するエンティティでは、データベースにアクセスするまで取得できません。
この状況に対する私の現在の回避策は次のとおりです。
/**
* Save an object into the database if it does not exist, else return
* object that exists in the database.
*
* @param query query to find object in the database, should only return
* one object.
* @param entity Object to save or update.
* @return Object in the database, whither it was prior or not.
*/
private Object saveOrUpdate(Query query, Object entity) {
final int NO_RESULT = 0;
final int RESULT = 1;
//should return a list of ONE result,
// since the query should be finding unique objects
List results = query.getResultList();
switch (results.size()) {
case NO_RESULT:
em.persist(entity);
return entity;
case RESULT:
return results.get(0);
default:
throw new NonUniqueResultException("Unexpected query results, " +
results.size());
}
}