Есть таблица в БД PostgreSql. У этой таблицы есть ограничение на уникальность для id. Сохраняю сущности в БД посредством Hibernate.
Код Entity:
@Entity
@Table(name = "cinema_movie")
public class Cinema_Movie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "cinema_id")
private String cinemaId;
@Column(name = "movie_id")
private String movieId;
Геттеры и сеттеры, плюс конструктор прилагаются. Не писал для сокращения кода.
Код сохранения в БД:
public void save() {
CinemaMovie cinema_movie = new CinameMovie();
cinema_movie.setCinemaId("random");
cinema_movie.setMovieId("random")
session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
session.save(cinema_movie);
}
Ну и в HibernateSessionFactoryUtil ничего особенного нет:
public static SessionFactory getSessionFactory() {
logger.debug("Start method getSessionFactory() at HibernateSessionFactoryUtil.class");
if (sessionFactory == null) {
try {
Configuration configuration = new Configuration().configure();
configuration.addAnnotatedClass(Cinema_Movie.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (Exception e) {
logger.error("Error at method getSessionFactory() at HibernateSessionFactoryUtil.class: ", e);
}
}
logger.debug("End of method getSessionFactory() at HibernateSessionFactoryUtil.class");
return sessionFactory;
}
И соответственно, метод save() вызывается переодически в разное время в программе. Изменения в БД в данную таблицу вносились руками, удалялись некоторые записи, т.к. программа только на стадии разработки.
Вопрос в следующем:
Как происходит генерация уникальных значений в Hibernate, и почему переодически я получаю ошибку:
ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ОШИБКА: повторяющееся значение ключа нарушает ограничение уникальности
?
А так же, как избежать данной ошибки, т.е. чтобы Hibernate точно гененрировал уникальные ID, которых еще нет в БД? Только дополнительной проверкой? Или сделать другой primary key, который самому генерировать? Или же есть какая то возможность исключения такой ошибки с помощью инструментов Hibernate?
Оригинал ответа можно найти тут.
В Hibernate есть возможность создания кастомных ID.
Вот примитивный вариант её реализации:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "player_generator")
@SequenceGenerator(name="player_generator", sequenceName = "player_seq", allocationSize = 1, initialValue = 1)
private Long id;
Итак:
generator = "player_generator"
- Это названия генератора, который будем использовать (название может быть любое. Главное в кавычках =) )
name="player_generator"
- Название кастомного генератора
sequenceName = "player_seq"
- это под каким названием будет создана таблица в базе данных
allocationSize = 1
(Optional. Можно не писать) - Это на сколько будет увеличиваться ваш id. [По дефолту - на 50]
initialValue = 1
(Optional. Можно не писать) - Это с какого числа начинается отсчет. [По дефолту - с 1]
Также на данном сайте рассказываются про разные стратегии:
Можете использовать стратегию increment. Она очень неэффективная, но должна решить вашу проблему (хотя бы на время разработки). При этом каждый раз при вставке сущности будет происходить обращение к базе для чтения последнего id. Для настройки надо определить генератор id.
@Entity
@Table(name = "cinema_movie")
public class Cinema_Movie {
@Id
@GeneratedValue(generator = "ID_GENERATOR")
private int id;
Так как он может использоваться сразу в нескольких сущностях, определим его на уровне пакета. Создадим файл package-info.java в пакете с сущностями:
package-info.java
@org.hibernate.annotations.GenericGenerator(
name = "ID_GENERATOR",
strategy = "increment",
parameters = {
@org.hibernate.annotations.Parameter(
name = "sequence_name",
value = "MY_SEQUENCE"
)
}
)
package com.project.entities; // имя пакета
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть массив объявлений, к каждому из которых генерируется метка на карте и карточка к нейПри клике на метку, должна отобразиться соответствующая...
Я пользуюсь VS Code и там же запускаю localhost для авто перезагрузки страницы (после сохранения файла)Но проблема в том, что после этой перезагрузки...
Необходимо реализовать алгоритм проверяющий наличие подстроки в массиве строк и возвращающая номера элементов массива, в которых встретилась...