2

In my code I remove and persist objects in the same transaction:

for (final GZAFixInterval actStat : actualStatus) {
        ...
        em.remove(actStat);
        ...
}

for (final Interval newInterval : newIntervals) {
    final GZAFixInterval newGZAfi = new GZAFixInterval();
    ... setters etc
    em.persist(newGZAfi);
}

em.flush();

Sometimes I get a PSQLException: ERROR: conflicting key value violates exclusion constraint "constraint_name". This is a special exclusion constraint.

The situation when constraint error occurs is as follows:

  1. em.remove(objectA)
  2. em.persist(objectB)

objectA and objectB must be mututally excluded from existing in the table (this is the constraint). Maybe objectA is not really removed from the DB before inserting objectB.

The question is: if this is the case, how to enforce JPA to really remove objectA before insering objectB? Sould a flush resolve it?

Currently I'm playing with deferred constraints, but any idea could be welcome.

gyorgyabraham
  • 2,550
  • 1
  • 28
  • 46

2 Answers2

4

EclipseLink does not process changes in the order they are pushed to the context. Instead, it either collects them in an unordered lists if change tracking is used, or calculates them on flush/commit otherwise.

Tom describes this behavior somewhat here http://old.nabble.com/Order-of-operations-in-EclipseLink-td30551198.html and points to the documentation for setShouldPerformDeletesFirst here: http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#How_to_Use_the_setShouldPerformDeletesFirst_Method_of_the_Unit_of_Work

Setting this flag though means all deletes will occur first, so if you want a specific ordering, you will need to use flush.

Chris
  • 20,138
  • 2
  • 29
  • 43
2

The flush() method writes changes of the current transaction to the database without terminating the transaction. So calling flush() would remove objectA from database.

However, my understanding of JPA is, that it should also work without a flush. That's why I am not sure if the flush will help you to solve the problem. When is the exception thrown, during commit?

Matt Handy
  • 29,855
  • 2
  • 89
  • 112
  • No, I got the error when calling explicitly em.flush() (as my example says at the end). – gyorgyabraham Mar 13 '12 at 11:51
  • Did you try the flush() between remove and persist? – Matt Handy Mar 13 '12 at 12:30
  • I'm currently trying that. Now it is possible to be a bug in the actual application's code. JPA / EclipseLink (usage/bug) is just another possibility. Thanks for the info. Will update my post with the results regarding deferred constraint application and flush between remove and persist. – gyorgyabraham Mar 13 '12 at 12:45
  • I put a flush() between remove and persist, also deferred the constraint. My bug reporter cannot reproduce the bug now. I'm not really sure which one solved the problem. – gyorgyabraham Mar 19 '12 at 08:47