15

有没有通用的方法可以

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

那么包含上述逻辑的方法到处都是安全的吗?

4

3 回答 3

18

如果您需要知道对象是否已经在持久化上下文中,您应该contains使用EntityManager.

只能EntityManager告诉你实体是否持久化,实体没有这样的信息。

在这里您可以检查 javadoc 的contains方法

if (!em.contains(entity)) {
  em.persist(entity);
} else {
  em.merge(entity);
}
于 2013-04-18T20:14:56.073 回答
4

要检查当前 PersistenceContext 是否已持久化实体对象,您可以使用 EntityManager 方法contains(Object entity)

于 2013-04-18T20:19:05.800 回答
1

也许为时已晚,但这是我的发现!如果您有一个具有生成值的实体,则可以使用它来检查该实体是否已经在数据库中,假设您没有手动修改此值。

@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.merge()而不是em.persist(),但并非没有成本。

对em.merge()的调用正在尝试使用SELECT查询从数据库中检索现有实体并对其进行更新。因此,如果实体从未被持久化,这将浪费一些 CPU 周期。另一方面em.persist()只会产生一个INSERT查询。

于 2020-07-07T15:29:24.217 回答