我已经配置了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行)

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

谢谢你。

有帮助吗?

解决方案

我有同样的问题。它与冬眠的ID分配策略有关。你选择 GenerationType。序列, ,Hibernate使用HILO策略,该策略默认情况下分配了50个块的ID。因此您可以明确设置 分配 这样的价值:

@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策略一起使用的意见 分配= 1 不是一个好习惯。有些人建议使用 enaentype.auto 相反,当您必须处理数据库管理的序列时

更新: 我确实最终会分配= 1,而且事情似乎正如我所期望的那样。我的应用程序使我真的不需要ID块,所以 YMMV.

其他提示

请勿使用Postgres序列的GenerationType。序列!

这完全是违反直觉的,但是冬眠的人们对此完全搞砸了。你 必须使用GenerationType.auto 或冬眠 拆除 如果您必须重新启动/重建数据库,则您的序列。他们将允许该代码进入生产建筑几乎是犯罪疏忽大意的,但是休眠团队以其斗牛头的立场而闻名(例如,查看他们在左联合的位置)。

首先,您必须确定您正在使用哪种版本的Hibernate。就冬眠核版本而言,3.2开始对ID发生器引入更一致的支持,尤其是在注释中定义的方面。看 http://in.relation.to/bloggers/new323HibernateIdentifierGenerators 进行讨论。

下一个3.6引入了一个设置('Hibernate.ID.NEW_GENERATOR_MAPPINGS'),该设置使该博客中讨论的生成器处理JPA通知的方式。默认情况下,该设置为错误,因为Hibernate必须保持与旧版本的向后兼容性。如果您想要新的行为(完全推荐),则只需将该设置设置为true即可。

GenerationType的处理方式取决于您使用的版本以及您是否具有“ Hibernate.ID.NEW_GENERATOR_MAPPING”设置为true。我会假设您使用的是3.6+(因为较旧的东西是旧的),并且确实具有'Hibernate.ID.NEW_GENERATOR_MAPPINGS'设置为true(因为这是新应用程序的建议):

  1. generationType.auto->被视为GenerationType.Sequerence
  2. generationType.sequence->映射到org.hibernate.id.enhanced.sequestestestylegenerator类中讨论的sequestestylegenerator类
  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并找到表,列或序列名称。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top