【问题标题】:nextVal from PostgreSQL sequence in Hibernate fetch sequence multiple times来自 PostgreSQL 序列的 nextVal 在 Hibernate 获取序列中多次
【发布时间】:2014-05-26 08:10:58
【问题描述】:

对于业务逻辑,我们需要使用直接在数据库中而不是在 Hibernate 中定义的序列中的下一个值来更新记录(因为并不总是应用于插入/更新)

为此,我们在 PostgreSQL 中定义了一个序列,其 DDL 为:

CREATE SEQUENCE public.facturaproveedor_numeracionperiodofiscal_seq
INCREMENT 1 MINVALUE 1
MAXVALUE 9223372036854775807 START 1
CACHE 1;

然后在DAO中,当某些条件为真时,我们通过:

Query query = sesion.createSQLQuery("SELECT nextval('facturaproveedor_numeracionperiodofiscal_seq')");
Long siguiente = ((BigInteger) query.uniqueResult()).longValue();

但是分配的值不是连续的。查看 Hibernate 输出日志,我们看到在同一事务中对序列进行了四次提取:

Hibernate: SELECT nextval('facturaproveedor_numeracionperiodofiscal_seq') as num
Hibernate: SELECT nextval('facturaproveedor_numeracionperiodofiscal_seq') as num
Hibernate: SELECT nextval('facturaproveedor_numeracionperiodofiscal_seq') as num
Hibernate: SELECT nextval('facturaproveedor_numeracionperiodofiscal_seq') as num

为什么会这样?这是为了捕捉目的吗?有办法禁用这个吗?或者这个解决方法不正确?

【问题讨论】:

    标签: java sql hibernate postgresql


    【解决方案1】:

    Hibernate 通常不会生成看起来像这样的独立 nextval 调用,因此如果是您的应用程序执行多次提取,我不会太惊讶。您需要收集更多的追踪信息才能确定。

    我认为你可能有一个更大的问题。如果您关心序列跳过值或留下孔,那么您使用了错误的工具来完成这项工作,您应该在UPDATE,可能是UPDATE my_id_generator SET id = id + 1 RETURNING id 的表中使用计数器。这锁定并发事务并且还确保如果事务回滚,更新被撤消

    相比之下,序列是并行操作的,这意味着当事务回滚时,不可能回滚序列增量(请参阅 PostgreSQL 文档)。因此,它们通常不适合会计用途,例如发票编号和其他需要无缝序列的事情。


    对于其他没有特定要求只有时生成值的读者:不要手动生成序列值;使用@GeneratedValue 注释。

    在 Hibernate 3.6 和更高版本中,您应该在 Hibernate 属性中设置 hibernate.id.new_generator_mappings

    假设您从 PostgreSQL SERIAL 列映射生成的密钥,请使用映射:

    @Id
    @SequenceGenerator(name="mytable_id_seq",sequenceName="mytable_id_seq", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="mytable_id_seq")
    

    如果您省略了allocationSize,那么 Hibernate 会假定它是奇怪的默认值 50,并且 无法检查序列是否实际增加了 50,因此它会尝试插入已使用的 ID 并失败。

    Hibernate/JPA 无法自动为您的非 ID 属性创建值。 @GeneratedValue 注解仅与@Id 结合使用以创建自动编号

    【讨论】:

    • Hibernate/JPA 无法自动为您的非 ID 属性创建值。 @GeneratedValue 注解仅与@Id 结合使用以创建自动编号
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 2019-04-12
    • 2017-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    相关资源
    最近更新 更多