簡體   English   中英

PostgreSQL序列的incumps_by如何與Hibernate的allocationSize一起使用?

[英]How does increment_by of a PostgreSQL sequence work with the allocationSize of Hibernate?

我已經使用Hibernate,PostgreSQL和Spring設置了一個測試應用程序,並且不斷遇到這個莫名其妙的錯誤。 我希望這里的人可以闡明這個問題。

我的實體看起來像這樣:

@Entity
@Table(name = "something")
public class Something {

    @Id
    @SequenceGenerator(name = "somethingGen", sequenceName = "something_id_seq", allocationSize = 30)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "somethingGen")
    @Column(name = "id", unique = true, nullable = false)
    private long id;

    public Something() {
    }

    public long getId() {
        return id;
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", Something.class.getSimpleName() + "[", "]")
                .add("id=" + id)
                .toString();
    }
}

為了進行測試,我創建了一個Spring Data Repository,插入了五個條目並將其取回:

System.out.println("starting...");

for (int i = 0; i < 5; i++) {
    repository.save(new Something());
}

repository.findAll().forEach(System.out::println);

第一次啟動此代碼時,它幾乎可以按預期工作:

Something[id=1]
Something[id=2]
Something[id=3]
Something[id=4]
Something[id=5]

但是,第二次我以這個異常結束: org.hibernate.MappingException: The increment size of the [something_id_seq] sequence is set to [30] in the entity mapping while the associated database sequence increment size is [1].

因此,我檢查了Postgres DB中的序列:

uat=# \d something_id_seq
      Sequence "public.something_id_seq"
    Column     |  Type   |        Value        
---------------+---------+---------------------
 sequence_name | name    | something_id_seq
 last_value    | bigint  | 1
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 32
 is_cycled     | boolean | f
 is_called     | boolean | t

這是第一個問題。 似乎Hibernate正在使用錯誤的增量值創建序列。 因此,我更改了increasing_by值: alter sequence something_id_seq increment 30並再次啟動我的代碼,並最終得到以下輸出:

Something[id=1]
Something[id=2]
Something[id=3]
Something[id=4]
Something[id=5]
Something[id=901]
Something[id=902]
Something[id=903]
Something[id=904]
Something[id=905]

現在序列看起來像這樣:

---------------+---------+---------------------
 sequence_name | name    | something_id_seq
 last_value    | bigint  | 31
 start_value   | bigint  | 1
 increment_by  | bigint  | 30

所以,在我看來,新的ID通過計算increment_by * allocation_size + last_value ,但我期待新的ID是30( allocation_size * last_value ),因為我懷疑increment_byallocationSize是因為MappingException同樣的事情。

這給我留下了兩個問題:

  1. 我期望id大約為0、30、60、90 ...,而最終我得到的id大約為1和900。SequenceGenerator的javadoc指出,distributionSize是the amount to increment by when allocating sequence numbers from the sequence 這是否意味着increment_byallocationSize是不同的東西? 它們如何聯系在一起(例如,為什么會看到MappingException )以及如何實現預期的行為?

  2. MappingException向我指示Hibernate正在使用錯誤的增量值創建序列。 我如何讓Hibernate創建正確的Hibernate?

我正在使用Hibernate 5.4.2.Final和PostgreSql 9.6.12以及以下設置:

HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setDatabase(Database.POSTGRESQL);
hibernateJpaVendorAdapter.setDatabasePlatform(PostgreSQL9Dialect.class.getName());
hibernateJpaVendorAdapter.setGenerateDdl(true);

我懷疑問題可能出在HiLo發電機上,但對於我一生,我無法弄清楚:

hibernate.id.new_generator_mappings=true
hibernate.id.optimizer.pooled.preferred=hilo
hibernate.schema_update.unique_constraint_strategy=RECREATE_QUIETLY

increment_byallocationSize必須具有相同的大小。 但是,除非你有一個分布式的刀片式稱重系統,你應該去與默認increment_by 1,並使用@GeneratedValue(strategy = GenerationType.IDENTITY)

您可能最終跳到900,因為各種線程都保留了ID,但隨后插入失敗。 我有那個問題。 現在,我插入IDENTITY

至於MappingException,所述something_id_seq序列由Postgres自動創建,因為PostgreSQL的方言使用serialbigserial創建表時。 參見PostgreSQL81IdentityColumnSupport 也許還應該考慮,Hibernate並不改變該序列的一個bug allocationSize ,你可以舉報。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM