JPA2 уникальное ограничение: мне действительно нужно сбросить? - PullRequest
4 голосов
/ 19 октября 2010

У меня есть DAO, где мне нужно поймать исключение из уникального ограничения.Для этого единственное рабочее решение - сбросить мой EntityManager после сохранения.Только тогда я попадаю в блок catch, где я должен отфильтровать исключение.И мой метод DAO должен быть включен в транзакцию (REQUIRES_NEW), в противном случае у меня возникает исключение RollBackException.

Я что-то не так делаю?

try {
        em.persist(myObject);
        em.flush();
    } catch (PersistenceException ex) {
        if (ex.getCause() != null) {
            String cause = ex.getCause().toString();
            if (cause != null) {
                if (cause.contains("org.hibernate.exception.ConstraintViolationException")) {
                    logger
                            .error("org.hibernate.exception.ConstraintViolationException: possible unique constraint failure on name");
                    throw ex;
                }
            }
        }
    }

1 Ответ

2 голосов
/ 20 октября 2010

Я что-то не так делаю?

EntityManager#persist() не вызовет немедленную вставку (если вы не используете стратегию IDENTITY).Так что, если вы действительно хотите записать изменения в памяти в базу данных и получить возможность отследить нарушение ограничения, вам придется flush() «вручную» (хотя даже это не гарантирует ничего, ваша база данных может быть настроена)использовать отложенные ограничения ).

Другими словами, то, что вы делаете, - это IMO, просто правильный путь.


У меня естьсервисный метод с @Transactional (ОБЯЗАТЕЛЬНО), называемый addNewObject ().В этом методе происходит что-то, что может вызвать исключение (и, таким образом, откат транзакции).Одним из таких вызовов является вызов метода DAO addObject.Этот может потерпеть неудачу из-за уникального ограничения.Теперь, если я сделаю сброс, объект будет сохранен, если нет уникального нарушения.Тем не менее, внутри службы все еще может быть что-то еще, что заставляет метод генерировать исключение.

Я думаю, что вы путаете flush и commit.Если что-то идет не так за пределами addObject и выдает неисправимое исключение (но внутри той же транзакции), вся транзакция будет откатываться, включая операторы INSERT, соответствующие вызовам persist().Подводя итог, flush! = commit.

...