簡體   English   中英

從 PostgreSQL 序列中的 nextVal 在 Hibernate 獲取序列中多次

[英]nextVal from PostgreSQL sequence in Hibernate fetch sequence multiple times

對於業務邏輯,我們需要使用直接在數據庫中而不是在 Hibernate 中定義的序列中的下一個值來更新記錄(因為並不總是應用於插入/更新)

為此,我們在 PostgreSQL 中定義了一個序列,其中 DDL 為:

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

然后在 DAO 中,當某些條件為真時,我們通過以下方式獲得 nextVal:

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

但是分配的值不是連續的。 查看 Hibernate output 日志,我們看到在同一事務中對序列進行了四個提取:

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

為什么會這樣? 這是為了捕捉目的嗎? 有辦法禁用這個嗎? 或者這種解決方法不正確?

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 緩存查詢結果。

注意“as num”,看起來 hibernate 也在改變 SQL。

您應該能夠告訴 Hibernate 不要緩存結果

query.setCacheable(false);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM