Автор оригинала: Vlad Mihalcea.
Как я уже упоминал, вам никогда не следует использовать генератор идентификаторов ТАБЛИЦ, так как он неправильно масштабируется . В этом посте я покажу вам, почему вы не должны полагаться на стратегию AUTO
| GenerationType , если ваше приложение Hibernate использует MySQL.
В режиме гибернации 4, если у вас было следующее сопоставление сущностей:
@Entity(name = "Post") @Table(name = "post") public class Post { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; public Post() {} public Post(String title) { this.title = title; } }
При сохранении 3 Сообщения
сущностей:
for ( int i = 1; i <= 3; i++ ) { entityManager.persist( new Post( String.format( "High-Performance Java Persistence, Part %d", i ) ) ); }
Hibernate создаст следующие инструкции insert:
INSERT INTO post (title) VALUES ('High-Performance Java Persistence, Part 1') INSERT INTO post (title) VALUES ('High-Performance Java Persistence, Part 2') INSERT INTO post (title) VALUES ('High-Performance Java Persistence, Part 3')
Это здорово! Hibernate использовал столбец IDENTITY для создания идентификатора сущности, который является единственным разумным вариантом для MySQL.
Если вы запустите тот же модульный тест в Hibernate 5, вы получите следующие инструкции SQL:
SELECT next_val as id_val FROM hibernate_sequence FOR UPDATE UPDATE hibernate_sequence SET next_val= 2 where next_val=1 SELECT next_val as id_val FROM hibernate_sequence FOR UPDATE UPDATE hibernate_sequence SET next_val= 3 where next_val=1 SELECT next_val as id_val FROM hibernate_sequence FOR UPDATE UPDATE hibernate_sequence SET next_val= 4 where next_val=3 INSERT INTO post (title, id) VALUES ('High-Performance Java Persistence, Part 1', 1) INSERT INTO post (title, id) VALUES ('High-Performance Java Persistence, Part 2', 2) INSERT INTO post (title, id) VALUES ('High-Performance Java Persistence, Part 3', 3)
Что только что произошло? Что ж, Hibernate выбирает генератор ТАБЛИЦЫ
вместо ИДЕНТИФИКАТОРА
, когда базовая база данных не поддерживает последовательности. Однако ТАБЛИЦА
генератор не является хорошим выбором. Ознакомьтесь с проблемой HHH-11014 Jira для получения более подробной информации, связанной с этим изменением поведения.
Исправить это чрезвычайно просто. Вам просто нужно вместо этого использовать собственный
идентификатор:
@Id @GeneratedValue( strategy= GenerationType.AUTO, generator="native" ) @GenericGenerator( name = "native", strategy = "native" ) private Long id;
Теперь при запуске предыдущего тестового набора Hibernate вместо этого использует столбец идентификаторов:
INSERT INTO post (title) VALUES ('High-Performance Java Persistence, Part 1') INSERT INTO post (title) VALUES ('High-Performance Java Persistence, Part 2') INSERT INTO post (title) VALUES ('High-Performance Java Persistence, Part 3')
Если вы хотите использовать портативное решение, которое позволяет настраивать генератор ПОСЛЕДОВАТЕЛЬНОСТИ
, сохраняя при этом возможность выбора ИДЕНТИФИКАТОРА
генератора для MySQL, то ознакомьтесь с этой статьей .
Переносимость JPA-это миф! На самом деле вам необходимо знать подробные сведения о базовом поставщике JPA, если вы хотите высокопроизводительное корпоративное приложение.