できる一般的な方法はありますか
if(entity is persisted before){
entity = entity.merge();
}else{
entity.persist();
}
したがって、上記のロジックを含むメソッドはどこでも安全ですか?
できる一般的な方法はありますか
if(entity is persisted before){
entity = entity.merge();
}else{
entity.persist();
}
したがって、上記のロジックを含むメソッドはどこでも安全ですか?
エンティティ オブジェクトが現在の PersistenceContext によって永続化されているかどうかを確認するには、EntityManager メソッドのcontains(Object entity)を使用できます。
手遅れかもしれませんが、これが私の発見です!値を生成するエンティティがある場合は、この値を手動で変更していないと仮定して、それを使用してエンティティが既に 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クエリのみを生成します。