24

Does remove(Object entity) method of EntityManager work only on those objects got from find() method?

I have following code snippet:

public void deletePerson() {
    EntityManager em = getEntityManager();
    Person p = new Person("x", "y", 200);
    em.remove(p);
}

But it is not removing the particular entry from database.

When I tried something like below:

public void deletePerson() {
    EntityManager em = getEntityManager();
    Person p = em.find(Person.class, 200);
    em.remove(p);
}

It's working fine.

4 Answers 4

26

Quoting from ObjectDB's manual on deleting JPA entity objects:

In order to delete an object from the database it has to first be retrieved (no matter which way) and then in an active transaction, it can be deleted using the remove method.

An IllegalArgumentException is thrown by remove if the argument is not a an instance of an entity class or if it is a detached entity.

When creating object with new operator, it becomes a detached entity, you need to persist it if you want to remove it.

When retrieving entity, you are retrieving persistent entity.

4
  • Given the above statement, is em.remove(em.merge(person)) - where person has been retrieved from the database - a correct way to delete the object?
    – dendini
    Commented Jan 23, 2014 at 9:12
  • @dendini No, if person has been retrieved from the database, then it means that it exists in the database. So, in this case, you can call directly em.remove(person). Commented Sep 17, 2014 at 10:09
  • 4
    So you need SELECT then DELETE which are 2 queries while you can do it in a single native DELETE. Why redundant when it comes to JPA?
    – sura2k
    Commented May 14, 2016 at 11:09
  • 1
    @sura2k because of possible inconsistencies of cascaded/associated entities (collections) that may be different and the remove would not know what how to do it correctly: stackoverflow.com/a/16089671/1915920 Commented Nov 18, 2016 at 8:19
14

Something to that direction. EntityManager.remove works only for managed entities. How you obtained these managed entities does not matter, it can be for example:

  • via JPQL query
  • via Criteria API query
  • find method in EntityManager
  • by following relationship from some other entity.
  • created new entity and persisted it

But simply creating new object and trying to remove it does not work, because this new object is not managed entity. Also entity should not be yet detached.

Life of entity is quite much as follows, all in same transaction (entities outside their transaction are not managed):

Entity ent = new Entity(1); //entity is in new state, EntityManager never know
                            //anything about it
em.persist(ent); //entity is managed as long as not disconnected 
                 //from EntityManager
em.clear(); // all previously managed entities, including ent, are now detached

Entity same = em.find(1); //managed same
em.remove(same); // entity is removed
1
  • Thanks for the example. Now I got the idea of detached entity. Still think it should throw some exception saying "entity not present or something" Commented Jul 18, 2012 at 11:24
3

Yes in case of merge or remove operation you have to use a find() operation and then use the remove method on the retrieved entity.

1
  • there is no findBy operation in JPA - have edited the answer, awaiting review
    – him
    Commented Jan 11, 2019 at 16:25
3

With JPA, you can remove an entity without retrieving it by simply executing a delete statement:

// em is your instance of EntityManager
javax.persistence.Query q = em.createQuery("delete from A where id = :id");
q.setParameter("id", "value of id to delete");
int deletedRows = q.executeUpdate();
1
  • Does it do the Cascade as well ? Commented Mar 30, 2023 at 10:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.