0

I used this JPA: check whether an entity object has been persisted or not to know if i persist or merge my entity , It will look like this :

if (!getEntityManager().contains(entity)) {
        System.out.println(" PERSIST ");            
    } else {
        System.out.println(" MERGE ");
    }

The case is that - even if I edit my entity - it will not recognized as a merge.

How is it possible and how to make it work?

MWiesner
  • 8,868
  • 11
  • 36
  • 70
Yagami Light
  • 1,756
  • 4
  • 19
  • 39

1 Answers1

6

According to the JPA 2.1 specification (PDF page 72),

the EntityManager method public boolean contains(Object entity) does:

Check if the instance is a managed entity instance belonging to the current persistence context.

For this reason, the check is not conducted against the actual database, but against the current persistence context.

Moreover, on PDF page 86 of the spec document we find:

The contains method returns true:

• If the entity has been retrieved from the database or has been returned by getReference, and has not been removed or detached.

• If the entity instance is new, and the persist method has been called on the entity or the persist operation has been cascaded to it.

The contains method returns false:

• If the instance is detached.

Most likely, you have a detached entity state in the moment the calling code of the code snippet is executed. Thus, the call for contains(..) always evaluates to false.

As an alternative, you can use

  • public <T> T find(Class<T> entityClass, Object primaryKey) (see p. 66) or
  • public <T> T getReference(Class<T> entityClass, Object primaryKey) (see p. 68)

to check the presence as a tuple in the underlying database. Which one of the above methods you chose will depend on the context of your code/application.

Hope it helps.

Community
  • 1
  • 1
MWiesner
  • 8,868
  • 11
  • 36
  • 70
  • Thank you for your answer, i think it will be completed if you add an example (how to use it) about the two alternative answers it will be the greatest answer ever. – Yagami Light Mar 06 '18 at 07:09
  • I found ever a better solution are you interested to improve your answer to make it a better one ?!? – Yagami Light Mar 06 '18 at 09:48
  • read the answer with one upvote (it was me ) (How to get the primary key of any JPA entity? )[https://stackoverflow.com/questions/3328813/how-to-get-the-primary-key-of-any-jpa-entity/46073932#46073932] – Yagami Light Mar 06 '18 at 12:00
  • This might be specific to certain Persistence providers only, such as Hibernate or Eclipselink and might not work in pure JPA style. Will check on this during the next days. And I think: Maybe, this is beyond the scope of the original question about `contains(..)`. – MWiesner Mar 06 '18 at 12:11
  • Yes i totally agree with you but the answer that i provided to you can used instead of `contains(..)` as an alternative solution – Yagami Light Mar 06 '18 at 12:41