Как настроить аннотации JPA для генерации идентификатора (первичного ключа) на уровне базы данных? - PullRequest
0 голосов
/ 14 ноября 2018

Предположим, у меня есть первичный ключ ts типа Timestamp.Это поле генерируется автоматически при вставке в мою таблицу PostgreSQL.Я хочу сказать JPA / Hibernate не отправлять или заполнять это поле, а просто игнорировать его, когда сущность сохраняется.

...

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "mygenerator")
@TableGenerator(name = "mygenerator", table = "ms.time_series")
@Column(name = "ts", insertable = false, updatable = false, columnDefinition= "TIMESTAMP WITHOUT TIME ZONE")
private Timestamp ts; 
...

Я не могу заставить его работать.Похоже, что @Id и @Columns(insertable = false, updatable = false) не работают вместе, этот параметр игнорируется, и фреймворк пытается изменить или отправить значение в любом случае.

Я использую последнюю версию Spring 5 и Spring Data 2.1.2 с Hibernate.База данных PostgreSQL.

Есть идеи, что может быть не так?Как правильно настроить аннотации, чтобы это работало?

1 Ответ

0 голосов
/ 14 ноября 2018

В момент отображения реляционного объекта у нас есть возможность определить, как мы будем обрабатывать первичные ключи: если мы собираемся привести приложение в приложение, чтобы определить это единственное значение (когда мы объявляем только@Id аннотации), или если мы собираемся оставить эту ответственность за провайдером персистентности (когда мы также объявляем аннотацию @GeneratedValue).

При цитировании термина провайдер персистентности знайте, что мы ссылаемся навыбранный фреймворк, чтобы приложение могло общаться с базой данных.Вот некоторые примеры: Hibernate, EclipseLink и OpenJPA.


GenerationType.AUTO

GenerationType.AUTO является типом генерации по умолчанию и позволяет провайдеру постоянства выбирать генерациюстратегии.

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

GenerationType.IDENTITY

GenerationType.IDENTITY является самым простым в использовании, но не лучшим с точки зрения производительности.Он основан на автоматически увеличивающемся столбце базы данных и позволяет базе данных генерировать новое значение при каждой операции вставки.С точки зрения базы данных, это очень эффективно, поскольку столбцы с автоинкрементом высоко оптимизированы и не требуют каких-либо дополнительных операторов.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

GenerationType.SEQUENCE

GenerationType.SEQUENCE - мой предпочтительный способ генерации значений первичного ключа и использование последовательности базы данных для генерации уникальных значений.

Для получения следующего значения из последовательности базы данных требуются дополнительные операторы select.Но это не влияет на производительность для большинства приложений.И если вашему приложению необходимо сохранить огромное количество новых сущностей, вы можете использовать некоторые специфичные для Hibernate оптимизации, чтобы уменьшить количество операторов.

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

GenerationType.TABLE

The GenerationType.TABLE в наше время используется крайне редко.Он моделирует последовательность, сохраняя и обновляя ее текущее значение в таблице базы данных, что требует использования пессимистических блокировок, которые помещают все транзакции в последовательный порядок.Это замедляет работу вашего приложения, и поэтому вы должны предпочесть GenerationType.SEQUENCE, если ваша база данных поддерживает последовательности, что делают большинство популярных баз данных.

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

Рекомендация:

@Id
@GeneratedValue(strategy=GenerationType.TABLE)
@Column(name = "ts", columnDefinition = "TIMESTAMP WITHOUT TIME ZONE",
                     insertable = false, updatable = false)
private Timestamp ts; 

Ссылка:

...