Search code examples
javajpaeclipselink

EclipseLink 2.5 still throwing IntegrityConstraintViolation when persisting entity, after record is deleted from database


This is the sequence:

  1. App1: Persist Entity on database with ID=1. No problem.
  2. App2: External application deletes that same record with ID=1. No problem.
  3. App1: Tries to persist again the entity previous deleted by App2, here throws an exception saying "IntegrityConstraintViolation", as if the record were still in the database, and I'm inserting it twice, which is not.

The thing is that as I see, the EntityManager is using the cache to validate the Integrity f the database. And somehow, even after I call

getEM().getEntityManagerFactory().getCache().evictAll(); or getEM().clear();

the EntityManager is keeping that record in cache somehow, and I'm running out of ideas about how to clear that cache. One workaround I found was to call from App1:

getEM().remove(entity.class, id);

and it effectively removes the record from the database and from the EntityManager cache too. But, this is not the point, it only proves that it's using the cache for validation, but the main problem persists, "I cannot persist the record again after being deleted from another application".

BTW, I also tried refreshing the entity, and does not work either. It throws an exception saying the Entity is not managed.

Anybody have any ideas on how to solve this?


Solution

  • Finally solved the situation, this version of EclipseLink 2.5 behaves a bit different than previous versions, and this is one of the differences. The problem was that I was executing this line at the 'tearDown()' method of the TestClass:

    em.CreateQuery("delete from mytable").executeUpdate();
    

    to clean the tables in database. Even when this line effectively deletes the record from the database, if you're using the same EntityManager, then it will not remove it from the cache no matter what you do. So, I just moved the query and created a @NamedQuery annotation in mytable Entity class, and called the NamedQuery instead of executing the SQL directly. So, my code in the 'tearDown()' method ended up being:

    em.CreateNamedQuery("emptyMyTableQuery").executeUpdate();
    

    And the @NamedQuery:

    @NamedQuery(name="emptyMyTableQuery", query="delete from mytable")
    

    Now it works perfectly.

    Honestly, even when in previous versions of EclipseLink this does not occur, I have to say that this new version 2.5 has several enhancements and improvements in several aspects, and few bugs fixed too. Well, hope this helps is somebody finds the same problem.