15

できる一般的な方法はありますか

 if(entity is persisted before){
     entity = entity.merge();
 }else{
     entity.persist();
 }

したがって、上記のロジックを含むメソッドはどこでも安全ですか?

4

3 に答える 3

4

エンティティ オブジェクトが現在の PersistenceContext によって永続化されているかどうかを確認するには、EntityManager メソッドのcontains(Object entity)を使用できます。

于 2013-04-18T20:19:05.800 に答える
1

手遅れかもしれませんが、これが私の発見です!値を生成するエンティティがある場合は、この値を手動で変更していないと仮定して、それを使用してエンティティが既に DB にあるかどうかを確認できます。

@Entity
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
   
    // getter...
}

public class Main {
    public static void main() {
        MyEntity myEntity1 = new MyEntity();
        MyEntity myEntity2 = em.find(MyEntity.class, 4);
        em.detach(myEntity2); // or em.close()

        // other stuff and modifications

        // begin transaction
        persistEntity(myEntity1); // will use persist()
        persistEntity(myEntity2); // will use merge()
        // commit transaction

    }

    // This will manage correctly entities in different state
    public void persistEntity(MyEtity entity) {
        if (myEntity.getId() != null) em.merge(entity);
        else em.persist(entity);
    }
}

次のシナリオでは、 em.contains(entity)を使用すると失敗します。

public static void main(){
    MyEntity myEntity = em.find(MyEntity.class, 5);
    
    em.detach(myEntity); // or em.close()
  
    // We are going to execute persist() because the entity is detached
    if (!em.contains(myEntity)) 
        // This call will produce an exception org.hibernate.PersistentObjectException
        em.persist(myEntity);
    else 
        em.merge(myEntity);
}

OPがやろうとしていることを達成しようとするパフォーマンス上の理由があります。確かにem.persist()の代わりにem.merge( ) を使用できますが、コストがかかるわけではありません。

em.merge()への呼び出しは、 SELECTクエリを使用して DB から既存のエンティティを取得し、更新しようとしています。そのため、エンティティが永続化されていない場合、CPU サイクルがいくらか無駄になります。一方、em.persist()は 1 つのINSERTクエリのみを生成します。

于 2020-07-07T15:29:24.217 に答える