#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 будет запущен, когда вы этого захотите.