Как использовать существующую последовательность Oracle для создания идентификатора в спящем режиме? - PullRequest
25 голосов
/ 28 января 2010

У меня есть устаревшая база данных Oracle с последовательностью с именем 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 фактически не использует последовательность уже определено в БД.

Как мне заставить Hibernate использовать последовательность?

Ответы [ 10 ]

26 голосов
/ 25 октября 2011

Ответ на оригинальный вопрос:

@SequenceGenerator(name="EL_SEQ", sequenceName="EL_SEQ",allocationSize=1)

allocationSize устанавливает значение для увеличения на.

18 голосов
/ 28 января 2010

Я не привык использовать аннотации, это то, что есть в моем * .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>

Вы можете легко сопоставить это с аннотациями. Генератор идентификатор-последовательности использует автоинкремент с последовательностями.

8 голосов
/ 14 августа 2011

Вот рабочий пример с аннотациями, таким образом, будет использоваться существующая последовательность БД (вы также можете использовать стратегию «последовательности», но с меньшей производительностью при вставке):

@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;
    }
6 голосов
/ 28 декабря 2015

У меня была такая же проблема при обновлении с 3.5.5 до 5.0.6. Окончательный вариант.

Я решил это, переконфигурировав отображение в файле HBM из:

    <generator class="sequence">
        <param name="sequence">PRODUCT_ID_SEQ</param>
    </generator>

до:

    <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>
5 голосов
/ 27 мая 2014

Создайте свое имя последовательности в Oracle, например, contacts_seq. В вашем классе POJO. Определите следующую аннотацию для вашей последовательности.

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
4 голосов
/ 10 сентября 2013

Если вы используете javax.persistence.SequenceGenerator, hibernate использует hilo и, возможно, создаст большие пробелы в последовательности.Существует сообщение, посвященное этой проблеме: https://forum.hibernate.org/viewtopic.php?t=973682

есть два способа решения этой проблемы

  1. В аннотации SequenceGenerator добавьте allocSize = 1, initialValue = 1

  2. вместо использования javax.persistence.SequenceGenerator, используйте org.hibernate.annotations, например:

    @javax.persistence.SequenceGenerator (name = "Question_id_sequence",sequenceName = "S_QUESTION")

    @org.hibernate.annotations.GenericGenerator (name = "Question_id_sequence", стратегия = "sequence", параметры = {@Parameter (name = "sequence", значение = "S_QUESTION"))})

Я проверил оба способа, которые прекрасно работают.

2 голосов
/ 24 декабря 2015

allocSize и incrementBy - это совершенно разные вещи.

Hibernate, конечно, использует вашу последовательность, созданную в БД, но в зависимости от allocSize вы можете найти пробел в генерируемом значении.

Например, Предположим, что текущее значение последовательности равно 5, с шагом 1 в дБ и allocSize по умолчанию 50.

Теперь вы хотите сохранить коллекцию из 3 элементов через Hibernate, затем Hibernate назначит сгенерированный идентификатор 250, 251, 252

Это для целей оптимизации. Hibernate не должен возвращаться к БД и получать следующее увеличенное значение.

Если вы не хотите этого, просто установите allocationSize = 1, как уже ответили, и сделают цель

1 голос
/ 25 февраля 2014

Я использую следующее на PostgreSQL и работает просто отлично.

 @Id
 @GeneratedValue(generator = "my_gen")
 @SequenceGenerator(name = "my_gen", sequenceName = "my_seq_in_db")
 private int userId;
0 голосов
/ 22 января 2019

Во-первых: вы должны создать в вашей базе данных последовательность:

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>
0 голосов
/ 29 января 2011


По умолчанию Hibernate использует генератор последовательности HiLo, который, если у вас нет особых потребностей, это хорошо (с точки зрения производительности). Вы можете прочитать больше об этом в моем блоге здесь

Эяль

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...