EclipseLink JPA: удалить и сохранить в одной транзакции, ошибка ограничения - PullRequest
2 голосов
/ 13 марта 2012

В моем коде я удаляю и сохраняю объекты в одной транзакции:

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

Иногда я получаю PSQLException: ОШИБКА: конфликтующее значение ключа нарушает исключающее ограничение "constraint_name". Это специальное исключающее ограничение.

Ситуация, когда возникает ошибка ограничения, выглядит следующим образом:

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

objectA и objectB должны быть взаимно исключены из существующих в таблице (это ограничение). Может быть, объект А на самом деле не удален из БД перед вставкой объекта В.

Вопрос: если это так, как заставить JPA действительно удалить объект A перед вставкой объекта B? Может ли флеш решить это?

В настоящее время я играю с отложенными ограничениями, но любая идея может приветствоваться.

Ответы [ 2 ]

4 голосов
/ 13 марта 2012

EclipseLink не обрабатывает изменения в том порядке, в котором они помещаются в контекст.Вместо этого он либо собирает их в неупорядоченные списки, если используется отслеживание изменений, либо рассчитывает их при очистке / фиксации в противном случае.

Том немного описывает это поведение здесь http://old.nabble.com/Order-of-operations-in-EclipseLink-td30551198.html и указывает на документацию для setShouldPerformDeletesFirst здесь: http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#How_to_Use_the_setShouldPerformDeletesFirst_Method_of_the_Unit_of_Work

Хотя установка этого флага означает, что все удаления будут происходить первыми, поэтому, если выЕсли вы хотите сделать конкретный заказ, вам нужно будет использовать флеш.

2 голосов
/ 13 марта 2012

Метод flush() записывает изменения текущей транзакции в базу данных без прерывания транзакции. Таким образом, вызов flush() приведет к удалению объекта A из базы данных.

Однако я понимаю, что JPA также должно работать без флеша. Вот почему я не уверен, поможет ли этот процесс решить проблему. Когда генерируется исключение во время коммита?

...