Комментарии 12
Целая статья вместо того, что бы на sql написать insert on conflict do update
не все хотят видеть нативщину в коде
ну так-то любой туториал можно сократить до букв RTFM ) я как раз и хотел написать про то, что еще можно сделать, кроме добавления в код нативного SQL
Для меня эта статья полезная, т.к. только изучаю java, spring. Про существование "insert on conflict do update" в postgres не знал
Скромно упомяну про возможность использования @Version в entity классе
В итоге, первый insert выполнится успешно, а второй — свалится с ошибкой вставки по уникальному ключу (если вы, конечно, создали для внешнего идентификатора уникальный индекс).
По идее если используется сиквенса или UUID для внешнего идентификатора, то не будет дубликатов по ключу, но будет две одинаковые записи с разными ключами.
В статье я имею ввиду, что внешний идентификатор выдает не наша база, а какой-то сторонний сервис (поэтому он и внешний). Вы можете использовать как первичный ключ его, а можете сделать, чтобы первичный ключ генерировала база (я предпочитаю этот вариант). Но и во втором случае поле для внешнего ключа имеет смысл сделать уникальным, как раз чтобы ни при каких обстоятельствах не создались 2 записи с одинаковым внешним ID
NativeQuery возвращает количество измененных строк, а не сохраненный объект. Чтобы получить этот объект, нам надо выполнять отдельный запрос в БД, и при этом нет гарантий, что мы получим ровно то, что сами только что вставили;
Вы используете синтаксис Postgres. Просто допишите в конец "returning *" и DML запрос вернёт строки, подвергшиеся изменению.
Да, если мы используем PreparedStatement. Ну или вернее так - со Spring Data JPA это не сработает. При попытке объявить в репозитории модифицирующий метод, который возвращает не void и не int / Integer, вы получите ошибку, которая, собственно, и говорит:Modifying queries can only use void or int/Integer as return type!
А вы уберите @Modifying. Строго говоря, тут уже не совсем DML, но микс из DML+DQL. Данная аннотация просто изменяет способ интерпретации результата запроса.
Можете нагуглить на эту тему много интересного и на stackoverflow и github issues. У меня такой код есть в продакшн, и никаких блокировок не нужно.
Spring Data JPA и upsert