Hibernate为PostgreSQL插入生成两个不同的序列ID

Hibernate为PostgreSQL插入生成两个不同的序列ID,hibernate,postgresql,sequence,generated,Hibernate,Postgresql,Sequence,Generated,我使用序列生成的主键定义了一个实体: @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_key_gen") @SequenceGenerator(name = "id_key_gen", sequenceName = "id_key_seq") @Column(name = "id", unique = true, nullable = false) public int getId() { r

我使用序列生成的主键定义了一个实体:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_key_gen")
@SequenceGenerator(name = "id_key_gen", sequenceName = "id_key_seq")
@Column(name = "id", unique = true, nullable = false)
public int getId() {
    return this.id;
}
我使用的是PostgreSQL,这个键被定义为一个序列号。根据PostgreSQL

select last_value from id_key_seq;
返回

1603.
当我执行create()以持久化此实体的实例时,我在日志中看到以下内容(不相关的内容被编辑掉):


05 15:15:26.948 org.hibernate.id.enhanced.SequenceStructure[DEBUG]-获得的序列值:1604

05 15:15:26.948 org.hibernate.event.def.AbstractSaveEventListener[DEBUG]-生成的标识符:1554,使用策略:org.hibernate.id.enhanced.SequenceStyleGenerator


后续的SQL insert语句引用的是值1554,而不是它应该使用的值1604(基于SequenceStructure返回的值。Hibernate从何处获得1554

在我看来Hibernate有一个bug-SequenceStructure知道正确的下一个值,但它没有被使用。知道如何解决这个问题吗


仅供参考:我知道这是因为“Hibernate的人把事情搞砸了”,但除了这句没有多大帮助的话之外,就没有什么了。

看起来,如果使用GenerationType.SEQUENCE,则需要指定一个“增量值”1,以避免将序列用作Hi/Lo种子

您发布的问题的第一个答案(有用的答案)解释了您需要在@GeneratedValue注释中指定“allocationSize=1”


在较新的Hibernate版本中,您可以改为在Hibernate属性中设置
Hibernate.id.new\u generator\u mappings=true
;请参阅。

谢谢@araqnid,将allocationSize设置为1确实有效,但我对这种方法不是“良好做法”的评论感到好奇。将allocationSize设置为1是一种退化的情况,使HiLo样式的生成器可以像正常的序列生成器一样工作。OTOH,这是您需要的,所以请使用它。查看Hibernate 3.5中的代码,分配大小用于选择优化器实现,因此现在处理得很优雅。在我看来,Hibernate团队需要重新考虑他们的imp这是一个不必要的混淆。将allocationSize设置为1正是我所需要的,但我想知道这是否不应该是PostgreSQL上SEQUENCE的默认值。最好设置
hibernate.id.new_generator_mappings
,这会让一切变得更加正常。