Могу ли я продолжить транзакционную операцию после перехвата исключения? - PullRequest
0 голосов
/ 26 апреля 2020

Мой код выглядит примерно так:

@Transactional
public void save(Citizen citizen){
    this.saveCitizen(citizen);
}

private void saveCitizen(Citizen citizen){
    try{
        citizenReposiory.save(citizen);
    } catch(DataIntegrityViolationException exception){
          //Exception on the line below
          Citizen existingCitizen = citizenReposiory.findById(citizen.getId());
          exisitingCitizen.setAge(50);
    }
}

Сначала я пытаюсь спасти гражданина. Если исключение выдается, это потому, что гражданин уже существует в базе данных. В этом случае я хочу обновить существующую строку вместо. Однако в приведенном выше коде я получу еще одно исключение при вызове citizenReposiory.findById(citizen.getId());. Вот фрагмент терминала:

[26-04-2020 00:35] WARN  [o.h.engine.jdbc.spi.SqlExceptionHelper]  - SQL Error: 1062, SQLState: 23000
[26-04-2020 00:35] ERROR [o.h.engine.jdbc.spi.SqlExceptionHelper]  - Duplicate entry '10-2020-1' for key 'UKe4wgjj1wdqag5qhbcgnxhbvuj'
[26-04-2020 00:35] ERROR [org.hibernate.AssertionFailure]  - HHH000099: an assertion failure occurred 
(this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): 
org.hibernate.AssertionFailure: null id in dk.rsyd.mature.entities.WeeklyCare entry (don't flush the 
Session after an exception occurs)
org.hibernate.AssertionFailure: null id in dk.rsyd.mature.entities.WeeklyCare entry (don't flush the 
Session after an exception occurs)

Что здесь происходит? Разве невозможно продолжить транзакцию после получения исключения? Я пытался добавить @Transactional(noRollbackFor = DataIntegrityViolationException.class), но это не помогло.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Если «Объект Citizen», который вы отправляете в citizenReposiory.save (), уже имеет первичный ключ внутри. Может быть, вы можете просто вызвать saveOrUpdate () просто.

private void saveCitizen(Citizen citizen){

    citizenReposiory.saveOrUpdate(citizen);

}

FYI

  1. Hibernate поведение saveOrUpdate

  2. Способы сохранения () и saveOrUpdate () в спящем режиме

0 голосов
/ 26 апреля 2020

Можно использовать другой подход. То есть сначала вы можете выполнить findByID и убедиться, что findByID возвращает значение, если оно возвращает значение и, следовательно, оно уже существует, вы можете выполнить setAge операция, в противном случае вы можете сохранить гражданин. Таким образом, вы всегда будете выполнять предварительную проверку и избегать сохранения несуществующего объекта путем перехода в исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...