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

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.


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

To check if entity object has been persisted or not by the current PersistenceContext you can use the EntityManager method contains(Object entity)