简体   繁体   中英

JPA: check whether an entity object has been persisted or not

Is there a general method that can

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

So the method contain above logic is safe everywhere?

If you need to know is object already in persistence context you should use contains method of EntityManager .

Only EntityManager can tell you is entity persisted or not, entity does not have such information.

Here you can check javadoc for contains method .

if (!em.contains(entity)) {
  em.persist(entity);
} else {
  em.merge(entity);
}

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

Maybe it's too late, but here are my findings! If you have an entity with a generate value, you can use it to check if the entity is already in DB, assuming you are not modifying this value manually.

@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);
    }
}

Using em.contains(entity) will fail in this scenario:

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);
}

There are a performance reasons to try to achieve what OP is trying to do. You surely can use em.merge() instead of em.persist() , but not without a cost.

A call to em.merge() is trying to retrieve an existing entity from DB with a SELECT query and update it. So if the entity was never persisted, this will waste some CPU cycles. On the other side em.persist() will only produce one INSERT query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM