Контроль порядка обновлений в режиме гибернации

#java #hibernate #postgresql

#java #переход в режим гибернации #postgresql

Вопрос:

У меня есть таблица с уникальным столбцом «токен», к которому применяется уникальное ограничение в базе данных. В определенном случае мне нужно изменить существующую строку, чтобы она имела тот же токен, что и другая существующая строка, изменив 2-ю строку на новое значение.

Итак, допустим, у меня есть:

идентификатор; токен 0; ‘aaa’ 1; ‘bbb’

Я хочу, чтобы идентификатор 0 (‘aaa’) вместо этого имел токен ‘bbb’. Итак, мне нужно изменить ‘bbb’ на ‘jfeisefjse’, а затем я могу изменить ‘aaa’ на ‘bbb’. Это может быть сделано в postgres за один переход.

Я попытался сделать то же самое в коде: в одной транзакции я получаю токен из существующей строки (строка 1), я устанавливаю его в качестве случайного значения, я обновляю другую строку (строка 0), чтобы в ней был токен строки 1, затем я фиксирую. Однако режим гибернации не учитывает порядок, в котором я выполнял коммиты. Кажется, что сначала всегда выполняется инструкция update для строки 0, и postgres жалуется, что это нарушает ограничение внешнего ключа.

Как я могу заставить режим гибернации сделать это? Либо принудительно установить определенный порядок инструкций update, либо каким-то другим способом сделать это?

Примечание: Выполнение этого в двух транзакциях (одна для скремблирования строки 1, затем другая транзакция для обновления строки 0) не является вариантом.

Ответ №1:

Session.flush() заставит hibernate записать любой ожидающий SQL без фиксации транзакции. Это немного неуклюже, но иногда вам нужно немного уменьшить «ORM» и заставить вещи просто работать 🙂

Комментарии:

1. Спасибо, это работает. Это лучше, чем то, что я имел в виду в качестве резервной копии: напишите необработанный sql для этого и попросите hibernate выполнить это, чтобы выполнить обновление в правильном порядке. Спасибо

2. Предупреждение: режим гибернации будет игнорировать flush() всякий раз, когда ему этого захочется. Это никоим образом не гарантирует, что SQL будет запущен, когда вы этого захотите.