gpt4 book ai didi

java - PostgreSQL 序列的 increment_by 如何与 Hibernate 的 allocationSize 一起工作?

转载 作者:行者123 更新时间:2023-11-29 13:41:00 25 4
gpt4 key购买 nike

我已经使用 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 数据库中的序列:

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 正在创建具有错误增量值的序列。所以我更改了 increment_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 声明 allocationSize 是 分配时增加的数量来自序列的序列号。这是否意味着 increment_byallocationSize 不是一回事?它们如何结合在一起(例如,为什么我会看到 MappingException)以及如何实现我预期的行为?

  2. MappingException 向我表明 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 不改变序列到 allocationSize 的错误视为一个错误。 ,您可以举报。

关于java - PostgreSQL 序列的 increment_by 如何与 Hibernate 的 allocationSize 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55400776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com