Java – JPA – Генераторы – @SequenceGenerator

Я изучаю JPA и @SequenceGenerator annotations @SequenceGenerator .

Насколько я понимаю, он автоматически присваивает значение числовым идентификационным полям / свойствам объекта.

Q1. Создает ли этот генератор последовательности использование возможности создания числовой величины базы данных или генерирует ее собственный?

Q2. Если JPA использует функцию автоматического увеличения базы данных, то будет ли она работать с хранилищами данных, у которых нет функции автоматического увеличения?

Q3. Если JPA генерирует числовое значение самостоятельно, то как реализация JPA знает, какое значение будет генерироваться следующим? Проводит ли он сначала с базой данных, чтобы узнать, какое значение было сохранено последним, чтобы сгенерировать значение (последнее + 1)?


Q4. Кроме того, пролить свет на sequenceName и @SequenceGenerator свойства @SequenceGenerator annotations.

sequenceName – это имя последовательности в БД. Вот как вы указываете последовательность, которая уже существует в БД. Если вы идете по этому маршруту, вам нужно указать allocationSize который должен быть того же значения, что и последовательность DB, в качестве «автоматического приращения».

Применение:

 @GeneratedValue(generator="my_seq") @SequenceGenerator(name="my_seq",sequenceName="MY_SEQ", allocationSize=1) 

Если вы хотите, вы можете позволить ему создать последовательность для вас. Но для этого вы должны использовать SchemaGeneration, чтобы создать его. Для этого используйте:

 @GeneratedValue(strategy=GenerationType.SEQUENCE) 

Кроме того, вы можете использовать автоматическое поколение, которое будет использовать таблицу для генерации идентификаторов. Вы также должны использовать SchemaGeneration в какой-то момент при использовании этой функции, поэтому можно создать таблицу генераторов. Для этого используйте:

 @GeneratedValue(strategy=GenerationType.AUTO) 

Я использую это, и он работает правильно

 @Id @GeneratedValue(generator = "SEC_ODON", strategy = GenerationType.SEQUENCE) @SequenceGenerator(name = "SEC_ODON", sequenceName = "SO.SEC_ODON",allocationSize=1) @Column(name="ID_ODON", unique=true, nullable=false, precision=10, scale=0) public Long getIdOdon() { return this.idOdon; } 

Хотя этот вопрос очень старый, и я наткнулся на него по своим собственным проблемам с последовательностями JPA 2.0 и Oracle.

Хотите поделиться своими исследованиями по некоторым вещам –

Связь между @SequenceGenerator (allocSize) GenerationType.SEQUENCE и INCREMENT BY в определении последовательности данных

Убедитесь, что @SequenceGenerator (allocSize) установлено на то же значение, что и INCREMENT BY, в определении последовательности базы данных, чтобы избежать проблем (то же самое относится к исходному значению).

Например, если мы определим последовательность в базе данных с значением INCREMENT BY равным 20, установите для allocationsize в SequenceGenerator также значение 20. В этом случае JPA не будет звонить в базу данных до тех пор, пока она не достигнет следующей отметки 20, пока она не увеличивает каждый значение на 1 внутренне. Это экономит вызовы базы данных для получения следующего порядкового номера каждый раз. Побочным эффектом этого является: – всякий раз, когда приложение перераспределяется или сервер перезапускается между ними, он вызывает базу данных для получения следующей партии, и вы увидите подсказки в значениях последовательности. Также нам нужно убедиться, что определение базы данных и параметр приложения будут синхронизированы, которые могут быть недоступны все время, так как оба они управляются разными группами, и вы можете быстро потерять контроль над ними. Если значение базы данных меньше, чем распределение, вы увидите ошибки ограничения PrimaryKey из-за повторяющихся значений Id. Если значение базы данных выше, чем allocationsize, вы увидите подсказки в значениях Id.

Если для последовательности данных INCREMENT BY установлено значение 1 (что обычно делают администраторы баз данных), установите allocSize как 1 так, чтобы они были синхронизированы, но firebase database JPA вызывает каждый последующий порядковый номер.

Если вы не хотите каждый раз обращаться к базе данных, используйте страtagsю GenerationType.IDENTITY и установите значение @Id, заданное триггером базы данных. С GenerationType.IDENTITY, как только мы вызываем em.persist, объект сохраняется в БД, а значение для id присваивается возвращенному объекту, поэтому нам не нужно делать em.merge или em.flush . (Это может быть специфический поставщик JPA .. Не уверен)

Еще одна важная вещь –

JPA 2.0 автоматически запускает команду ALTER SEQUENCE, чтобы синхронизировать allocSize и INCREMENT BY в последовательности базы данных. Поскольку в основном мы используем другое имя схемы (имя пользователя приложения), а не фактическую схему, где существует последовательность, и имя пользователя приложения не будет иметь привилегий ALTER SEQUENCE, вы можете увидеть предупреждение ниже в журналах –

000004c1 Время выполнения W CWWJP9991W: openjpa.Runtime: Warn: невозможно кэшировать значения последовательности для последовательности «RECORD_ID_SEQ». У вашего приложения нет разрешения на выполнение команды ALTER SEQUENCE. Убедитесь, что у него есть соответствующее разрешение для запуска команды ALTER SEQUENCE.

Поскольку JPA не может изменить последовательность, JPA каждый раз обращается к базе данных, чтобы получить следующий порядковый номер независимо от значения @ SequenceGenerator.allocationSize. Это может быть нежелательным следствием, о котором нам нужно знать.

Чтобы JPA не запускала эту команду, установите это значение – в файле persistence.xml. Это гарантирует, что JPA не будет пытаться выполнить команду ALTER SEQUENCE. Он пишет другое предупреждение, хотя –

00000094 Runtime W CWWJP9991W: openjpa.Runtime: Warn: свойство “openjpa.jdbc.DBDictionary = disableAlterSeqenceIncrementBy” установлено в true. Это означает, что оператор SQL ALTER SEQUENCE … INCREMENT BY SQL не будет выполнен для последовательности «RECORD_ID_SEQ». OpenJPA выполняет эту команду, чтобы гарантировать, что значение INCREMENT BY последовательности, определенное в базе данных, соответствует распределению, которое определено в последовательности сущности. Когда этот оператор SQL отключен, пользователь должен убедиться, что определение последовательности сущности соответствует последовательности, определенной в базе данных.

Как отмечено в предупреждении, важно здесь: мы должны убедиться, что @ SequenceGenerator.allocationSize и INCREMENT BY в определении последовательности базы данных синхронизированы, включая значение по умолчанию @SequenceGenerator (allocSize), которое равно 50. В противном случае это вызовет ошибки.

У меня есть схема MySQL с автогенными значениями. Я использую strategy=GenerationType.IDENTITY тег и, кажется, отлично работает в MySQL. Думаю, он должен работать и с большинством db-движков.

 CREATE TABLE user ( id bigint NOT NULL auto_increment, name varchar(64) NOT NULL default '', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

User.java :

 // mark this JavaBean to be JPA scoped class @Entity @Table(name="user") public class User { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private long id; // primary key (autogen surrogate) @Column(name="name") private String name; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name=name; } } 
  • Hibernate против JPA против JDO - плюсы и минусы каждого?
  • Spring Boot, Spring Data JPA с несколькими источниками данных
  • Дилемма JPA hashCode () / equals ()
  • ConcurrentModificationException и HashMap
  • Как аннотировать поле автоинкремента MYSQL с аннотациями JPA
  • Пожалуйста, объясните: insertable = false, updatable = false
  • В чем разница между persist () и merge () в Hibernate?
  • Когда использовать EntityManager.find () vs EntityManager.getReference () с JPA
  • Неправильное упорядочение в сгенерированной таблице в jpa
  • Связь JPA Hibernate «один-к-одному»
  • Отображение Hibernate / JPA приводит к возникающим в JSF причинам: java.lang.NumberFormatException: для строки ввода: ""
  • Interesting Posts

    Как обновить страницу в ASP.NET? (Позвольте ему перезагрузить себя кодом)

    C # конструктор цепочки? (Как это сделать?)

    Process.Close () не завершает созданный процесс, c #

    Android Studio застряла на «Gradle: разрешить зависимости» _debugCompile »или« detachedConfiguration1 »

    Снять вертикальную прокладку с горизонтальной панели ProgressBar

    C #: должны ли переменные объектов присваиваться null?

    Преобразование строкового выражения в Integer Value с использованием C #

    Как рассчитать ширину текстовой строки определенного шрифта и размера шрифта?

    Как разработать расширяемое программное обеспечение (архитектура плагина)?

    Ошибка ANR keyDispatchingTimedOut

    Как установить Visual Studio 2010 Express где-нибудь, кроме C :?

    Как сделать полностью прозрачную навигационную панель в iOS 7

    Локальная групповая политика в Windows 7 – Откат по умолчанию?

    Ввод из скрипта оболочки

    Пользовательский текст UINavigationController “назад”?

    Давайте будем гением компьютера.