2014-11-02 3 views
0

У меня есть следующие модели:JPA/Ebean - заставить @Id строго увеличивается на +1 с PostgreSQL

public class Parameter extends Model { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    public long id; 
} 

Записи, созданные save() выглядеть следующим образом:

play=> select id from parameter; 
id 
---- 
    1 
    2 
    3 
    4 
    5 
21 
(6 rows) 

Есть способ, которым я могу сказать JPA, всегда увеличивать ìd ровно на один, вместо случайного перехода на 21?

+0

Короче - нет никакого способа, чтобы сделать это. Идентификационные поля гарантируют уникальность. –

ответ

1

То, что вы наблюдаете (переход на 21), скорее всего, будет частью имплантации Ebean до 4.0.5. Ebean использует механизм «выборки вперед» в последовательности. После 4.0.5 Ebean по умолчанию используется Postgres SERIAL (так что по умолчанию вы не увидите это с Ebean/Postgres после 4.0.5). Обратите внимание: https://github.com/ebean-orm/avaje-ebeanorm/issues/97

Все, что сказано - «incrementing ТОЧНО на 1» - это то, чего вы обычно хотите избежать, поскольку это становится проблемой параллелизма (избегайте того, чтобы идентификатор автоинкремента был транзакционным, поскольку это вводит конкуренцию). Если вам нужна семантика «приращение точно одной» (например, номера чеков и т. Д.), Вы можете посмотреть, чтобы создать в пакете заранее.

+0

Есть ли способ обеспечить, чтобы все ID были больше, чем любые предыдущие идентификаторы? Это было бы хорошо. – doque

+0

@doque В терминах Ebean он использует базовые последовательности БД (или автоинкремент БД в зависимости от БД), поэтому * обычно * да, вы заметите, что выделенные идентификаторы больше, чем любые предыдущие идентификаторы * HOWEVER *, которые строго не имеют и это может быть не так строго с Oracle RAC (или другими аналогичными кластеризованными БД, где блоки идентификаторов распределены между узлами БД). Вы можете проверить документы/поведение в своей базовой базе данных, но вы можете подумать, что безопаснее/лучше добавить столбец Timedamp 'when created' (с Ebean, который вы будете использовать @CreateTimestamp). –

+0

Сводка: последовательности БД (и автоинкремент) будут уникальными, могут иметь пробелы, как правило, но не строго возрастают (зависит от реализации БД, например, кластеризация БД, например, Oracle RAC), часто бывает полезно добавить дополнительный столбец timestamp 'whenCreated' помочь обеспечить упорядочение заказа, когда вы не можете или не хотите полагаться на «Идентификаторы, строго возрастают». –

0

Вы должны быть в состоянии достичь этого, используя @TableGenerator и allocationSize=1. Пример кода выглядит следующим образом. Вам нужно создать отдельную таблицу для хранения ПК, дополнительную работу, но более переносимую, чем @GeneratedValue.

@TableGenerator(name="MAIN_PK_GEN", table="pk_gen", pkColumnName="GEN_NAME", valueColumnName="GEN_VALUE", pkColumnValue="MAIN_PK_GEN", allocationSize=1) 
    @Id @GeneratedValue(strategy=GenerationType.TABLE, generator="MAIN_PK_GEN") 
    @Basic(optional = false) 
    @Column(name = "PK") 
    private Integer pk; 

(Но использование allocationSize=1 не может быть эффективным)

См this tutorial для пошагового объяснения.

0

Если вы используете Oracle не забудьте добавить SequenceGenerator с allocationSize 1:

@Id 
    @Column(name = "id") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "mysequence") 
    @SequenceGenerator(name = "mysequence", sequenceName = "mysequence", allocationSize = 1) 
    private Long id; 
Смежные вопросы