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

Gor*_*don 6 postgresql hibernate 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() {
    return this.id;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用PostgreSQL,这个键定义为串行.根据PostgreSQL

select last_value from id_key_seq;
Run Code Online (Sandbox Code Playgroud)

回报

1603.
Run Code Online (Sandbox Code Playgroud)

当我执行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插入语句引用值1554,而不是它应该使用的值1604(基于SequenceStructure返回的值.Hibernate从哪里获得1554?

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

仅供参考:我知道这个页面,它说要使用GenerationType.AUTO,因为"Hibernate人员完全搞砸了",但除此之外没有太多非常有帮助的陈述.

ara*_*nid 6

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

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

在较新的Hibernate版本中,您可以改为设置hibernate.id.new_generator_mappings=trueHibernate属性; 看文档.

  • 将allocationSize设置为1是一种退化情况,使HiLo型生成器作为正常序列生成器工作.OTOH,这是你需要的,所以使用它.查看Hibernate 3.5中的代码,分配大小用于选择优化器实现,因此现在可以正常处理它. (2认同)