Автор оригинала: Vlad Mihalcea.
В этой статье мы рассмотрим, как использовать идентификатор сущности UUID, который автоматически генерируется Hibernate либо в JVM, либо с помощью функций UUID, специфичных для базы данных.
Наш Пост
объект выглядит следующим образом:
Объект Post
имеет идентификатор UUID и заголовок. Теперь давайте посмотрим, как мы можем отобразить Опубликуйте
сущность, чтобы идентификатор UUID был автоматически сгенерирован для нас.
При использовании JPA мы можем использовать тип генерации . АВТО
стратегия аннотации @GeneratedValue
для автоматического присвоения числового идентификатора на основе столбца ИДЕНТИФИКАТОРОВ, ПОСЛЕДОВАТЕЛЬНОСТИ или печально известного генератора ТАБЛИЦ .
Однако мало кто может знать, что Тип поколения. AUTO
также может использоваться для идентификаторов UUID:
@Entity(name = "Post") @Table(name = "post") public class Post { @Id @GeneratedValue(strategy = GenerationType.AUTO) private UUID id; private String title; //Getters and setters omitted for brevity }
Теперь, когда сохраняется Сообщение
сущность:
Post post = new Post(); post.setTitle("High-Performance Java Persistence"); entityManager.persist(post);
Hibernate создает следующую инструкцию SQL INSERT:
INSERT INTO post ( title, id ) VALUES ( 'High-Performance Java Persistence', 'b5607d38-8fc1-43ef-b44e-34967083c80a' )
Даже дозирование работает так, как ожидалось:
for (int i = 0; i < 3; i++) { Post post = new Post(); post.setTitle( String.format( "High-Performance Java Persistence, Part %d", i + 1 ) ); entityManager.persist(post); }
Спящий режим, генерирующий одну инструкцию SQL INSERT с 3 наборами значений параметров привязки:
Query:[ "insert into post (title, id) values (?, ?)" ], Params:[ (High-Performance Java Persistence, Part 1, 7176589b-a3ca-472f-bf00-c253c351ddcc), (High-Performance Java Persistence, Part 2, a4269fb4-07c9-447a-9d65-f443c074de20), (High-Performance Java Persistence, Part 3, e33962a0-d841-48b1-8f43-caf98116f3ee) ]
Теперь, если мы не хотим, чтобы UUID создавался JVM, и хотим использовать функции, зависящие от базы данных, нам нужно предоставить реализацию org.hibernate.id. uuidgenerationстратегия
интерфейс:
public class PostgreSQLUUIDGenerationStrategy implements UUIDGenerationStrategy { @Override public int getGeneratedVersion() { return 4; } @Override public UUID generateUUID( SharedSessionContractImplementor session) { return ((Session) session).doReturningWork(connection -> { try( Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery( "select uuid_generate_v4()" ) ) { while (resultSet.next()) { return (UUID) resultSet.getObject(1); } } throw new IllegalArgumentException("Can't fetch a new UUID"); }); } }
Метод getGeneratedVersion
определяет, какой тип UUID мы генерируем, в соответствии со стандартом IETF RFC 4122. В нашем случае, 4
расшифровывается как вариант 4 (случайная) стратегия генератора.
Поскольку мы используем PostgreSQL, нам также необходимо создать расширение uuid-ossp
перед использованием функций, специфичных для UUID:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
Теперь мы можем вызвать функцию uuid_generate_v4
, чтобы получить UUID варианта 4 на основе спецификации IETF RFC 4122.
Чтобы предоставить PostgreSQL Стратегию генерации UUID
для нашей Post
сущности, мы должны использовать специфичный для гибернации @GenericGenerator
:
@Entity(name = "Post") @Table(name = "post") public class Post { @Id @GeneratedValue( strategy = GenerationType.AUTO, generator = "pg-uuid" ) @GenericGenerator( name = "pg-uuid", strategy = "uuid2", parameters = @Parameter( name = "uuid_gen_strategy_class", value = "com.vladmihalcea.book.hpjp.hibernate.identifier.uuid.PostgreSQLUUIDGenerationStrategy" ) ) private UUID id; private String title; //Getters and setters omitted for brevity }
Стратегия uuid2
означает org.hibernate.id. Генератор UUID
который мы хотим использовать вместо устаревшего org.hibernate.id. UUIDHexGenerator
это зарегистрировано под именем uuid
в режиме гибернации.
Атрибут @Parameter
используется для настройки UUIDgenerationstrategy с помощью uuid_gen_strategy_class
значение параметра, которое принимает полное имя класса org.hibernate.id. Uuidgenerationстратегия
реализация интерфейса.
И, вот оно что!
Теперь при сохранении 3 Post
сущностей Hibernate генерирует следующие инструкции SQL:
select uuid_generate_v4() select uuid_generate_v4() select uuid_generate_v4() Query:[ "insert into post (title, id) values (?, ?)" ], Params:[ (High-Performance Java Persistence, Part 1, 9eb52a9b-fb81-4930-b0cd-079a447ed2ba), (High-Performance Java Persistence, Part 2, 2a69ec7d-a147-4c71-8a20-9ba760de0149), (High-Performance Java Persistence, Part 3, e7616832-bb4e-470a-8df4-0534ab56d960) ]
Обратите внимание на вызовы функции uuid_generate_v4
PostgreSQL, которая используется для присвоения значений идентификаторов UUID.
Поэтому автоматическое создание идентификатора UUID при использовании Hibernate довольно просто.
Вы можете либо разрешить Hibernate использовать стратегию генерации UUID на основе Java, либо делегировать эту задачу базе данных. Последний вариант требует обеспечения реализации org.hibernate.id. Uuidgenerationстратегия
, которая довольно проста.