Ответ 1
Ответ на исходный вопрос:
@SequenceGenerator(name="EL_SEQ", sequenceName="EL_SEQ",allocationSize=1)
Это allocationSize
, которое устанавливает значение для увеличения на.
У меня есть устаревший Oracle db с последовательностью PRODUCT_ID_SEQ
.
Вот отображение класса Product
, для которого мне нужно создать правильные идентификаторы:
public class Product {
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "retailerRaw_seq")
@SequenceGenerator(name = "retailerRaw_seq",
sequenceName = "PRODUCT_ID_SEQ")
private Long id;
...
}
Но похоже, что идентификаторы генерируются с интервалом 50, например 1000, 1050, 1100 и т.д. Это соответствует значению по умолчанию allocationSize
property = 50. Таким образом, Hibernate фактически не использует последовательность, которая уже определен в db.
Как заставить Hibernate использовать последовательность?
Ответ на исходный вопрос:
@SequenceGenerator(name="EL_SEQ", sequenceName="EL_SEQ",allocationSize=1)
Это allocationSize
, которое устанавливает значение для увеличения на.
Я не использую аннотации, это то, что у меня есть в моем *.hbm.xml:
<id name="id" type="java.lang.Integer">
<column name="ID_PRODUCT" />
<generator class="sequence-identity" >
<param name="sequence">PRODUCT_ID_SEQ</param>
</generator>
</id>
Вы можете легко сопоставить это с аннотациями. Идентификатор последовательности-генератора использует автоматическое приращение с последовательностями.
Вот рабочий пример с аннотациями, таким образом, будет использоваться существующая последовательность БД (вы также можете использовать стратегию "последовательность", но с меньшей производительностью при вставке):
@Entity
@Table(name = "USER")
public class User {
// (...)
@GenericGenerator(name = "generator", strategy = "sequence-identity", parameters = @Parameter(name = "sequence", value = "USER_SEQ"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
public Long getId() {
return this.id;
}
Создайте свое имя последовательности в Oracle, например, contact_seq. В вашем классе POJO. Определите следующую аннотацию для вашей последовательности.
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
У меня была такая же проблема при обновлении с 3.5.5 до 5.0.6.Final.
Я решил его переустановить сопоставление в файле HBM с помощью
<generator class="sequence">
<param name="sequence">PRODUCT_ID_SEQ</param>
</generator>
to:
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="prefer_sequence_per_entity">true</param>
<param name="optimizer">none</param>
<param name="increment_size">1</param>
<param name="sequence_name">PRODUCT_ID_SEQ</param>
</generator>
Если вы используете javax.persistence.SequenceGenerator, hibernate использует hilo и, возможно, создаст большие пробелы в последовательности. Существует сообщение, в котором рассматривается эта проблема: https://forum.hibernate.org/viewtopic.php?t=973682
есть два способа исправить эту проблему.
В аннотации SequenceGenerator добавьте allocSize = 1, initialValue = 1
вместо использования javax.persistence.SequenceGenerator, используйте org.hibernate.annotations, например:
@javax.persistence.SequenceGenerator(name = "Question_id_sequence", sequenceName = "S_QUESTION" )
@org.hibernate.annotations.GenericGenerator(name= "Question_id_sequence", strategy = "sequence", parameters = {@Parameter (name= "sequence", value = "S_QUESTION" )})
Я тестировал оба способа, который работает отлично.
allocSize и incrementBy - это совершенно разные вещи.
Спящий режим, конечно, использует вашу последовательность, созданную в БД, но в зависимости от allocSize вы можете найти пробел в сгенерированном значении.
Например, Предположим, что текущее значение последовательности равно 5, приращение на 1 в db и allocSize по умолчанию 50.
Теперь вы хотите сохранить коллекцию из 3 элементов через спящий режим, затем Hibernate назначит сгенерированный идентификатор 250, 251, 252
Это для целей оптимизации. Hibernate не нужно возвращаться к db и получать следующее добавочное значение.
Если вы не хотите, чтобы это просто настройка allocationSize = 1
, как уже ответили, это сделает цель
Я использую следующее на PostgreSQL и отлично работает.
@Id
@GeneratedValue(generator = "my_gen")
@SequenceGenerator(name = "my_gen", sequenceName = "my_seq_in_db")
private int userId;
По умолчанию Hibernate использует генератор последовательности HiLo, который, если у вас нет особых потребностей, хорош (производительность разумна). Вы можете больше узнать об этом в моем блоге здесь
Эяль
Во-первых: вы должны создать в вашей базе данных следующую последовательность:
CREATE SEQUENCE "PRODUCT_ID_SEQ" MINVALUE 0 MAXVALUE 1000000000 INCREMENT BY 1 START WITH 1 CACHE 500 NOORDER NOCYCLE ;
и в вашем файле Product.hbm.xml конфигурации сделайте:
<class name="ProductPersistant" table="Product">
<id name="id" type="java.lang.Long" column="productID" >
<generator class="sequence">
<param name="sequence">PRODUCT_ID_SEQ</param>
</generator>
</id>