2009-07-16 3 views
35

、基本的にオブジェクトが既にデータベースに存在するかどうかをチェックしてあるかの新しいインスタンスを保存し、必要にオブジェクトのいずれかの更新あなたはHibernateのsaveOrUpdate behaviorを複製することができます任意の方法、JPAでHibernateのsaveOrUpdateをどのように複製できますか? JPAでは

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開発者はどのようにこれを処理しますか?

+0

"プライマリキー"がヌルかどうかを確認するにはどうすればよいですか? –

答えて

27

EntityManager.merge方法を試してください。これは非常に似ています。

Xebiaのブログポストの相違点は、「JPA Implementation Patterns: Saving (Detached) Entities」という優れた説明があります。

+6

私がここで大事にしているのは、「既存のエンティティを更新するときは、EntityManagerメソッドを呼び出さず、JPAプロバイダは自動的にフラッシュまたはコミット時にデータベースを更新します。 –

+1

リンクが無効です。ここに新しいものがあります:http://blog.xebia.com/jpa-implementation-patterns-saving-detached-entities/ – Dmitry

5

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()); 
    } 
} 
+1

mergeとsaveOrUpdateは表面的には似ていますが、同じではありません。セマンティクスには重要な違いがあります。 – skaffman

+0

@skaffman、あなたは私のアプローチに欠陥があると思いますか?それがあれば、建設的な批判を私のやり方で投げてくれますか?私はこのJPAもののために森の中のベイビーです。 –

+0

この古いスレッドが見つかりました。新しいJava ENUMSを除いてこのソリューションのようなものを実装しています。ありがとう。 – oberger

関連する問題