Hibernate使用PostgreSQL序列不会影响序列表

我已将Hibernate配置为使用PostgreSQL序列(通过注释)为主键id列生成值,如下所示:

@Id @SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq") @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence") @Column(name="id", unique=true, nullable=false) public int getId() { return this.id; } 

我在这个配置中看到的是,hibernate已经在持久化时分配了id值> 3000,而对使用过的序列的查询显示如下:

 database=# select last_value from entity_id_seq; last_value ------------ 69 

(1排)

问题:
有什么不对吗?
hibernate应该与序列表同步吗?
如果没有,它在哪里存储最后生成的ID?

谢谢。

我有同样的问题。 它与Hibernate的id分配策略有关。 当您选择GenerationType.SEQUENCE时 ,Hibernate使用HiLo策略,默认情况下以50块为单位分配ID。 所以你可以像这样显式设置allocationSize值:

 @Id @SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq", allocationSize=1) @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence") @Column(name="id", unique=true, nullable=false) public int getId() { return this.id; } 

虽然,我也听说过使用HiLo策略和allocationSize = 1的观点并不是一个好习惯。 有些人建议在必须处理数据库管理的序列时使用GenerationType.AUTO

更新:我最终使用allocationSize = 1,事情似乎正如我现在预期的那样。 我的应用是这样的,无论如何我真的不需要ID块,所以YMMV 。

不要为Postgres序列使用GenerationType.SEQUENCE!

这完全是违反直觉的,但Hibernate的人完全搞砸了。 如果必须重新启动/重建数据库,则必须使用GenerationType.AUTO或Hibernate将拆除序列。 他们允许这些代码进入生产版本几乎是犯罪过失,但是Hibernate团队因为他们对于错误的位置的牛头立场而非常有名(例如,查看他们在LEFT JOIN上的位置)。

首先,您必须确定您正在使用的Hibernate版本。 在hibernate-core版本方面,3.2以后为id生成器引入了更一致的支持,特别是在注释中定义的方面。 有关讨论,请参见http://in.relation.to/Bloggers/New323HibernateIdentifierGenerators 。

接下来3.6引入了一个设置(’hibernate.id.new_generator_mappings’),这使得该博客中讨论的生成器成为处理JPA注释的默认方式。 默认设置为false,因为Hibernate必须保持与旧版本的向后兼容性。 如果您想要新行为(完全建议使用),则只需将该设置设置为true即可。

如何处理GenerationType取决于您使用的版本以及是否将“hibernate.id.new_generator_mappings”设置为true。 我假设您使用的是3.6+(因为任何旧版本都是旧的)并且确实将’hibernate.id.new_generator_mappings’设置为true(因为这是对新应用的建议):

  1. GenerationType.AUTO – >视为GenerationType.SEQUENCE
  2. GenerationType.SEQUENCE – >映射到博客中讨论的org.hibernate.id.enhanced.SequenceStyleGenerator类
  3. GenerationType.TABLE – >映射到博客中讨论的org.hibernate.id.enhanced.TableGenerator类

在Postgres我会这样做:

 @Id @SequenceGenerator(name="pk_sequence",sequenceName="\"entity_id_seq\"") @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="\"pk_sequence\"") @Column(name="\"id\"", unique=true) private int id; 

主要使用大写名称Hibernate需要传递转义引号才能理解Postgres并找到表,列或序列名称。