Hibernate无法获取下一个序列值

Hibernate无法获取下一个序列值,第1张

Hibernate无法获取下一个序列

Hibernate的PostgreSQL方言不是很聪明。它不了解您的每个串行序列,并假设可以使用一个全局数据库范围的序列“
hibernate_sequence”。


更新
:似乎在

GenerationType.IDENTITY
指定时,较新的Hibernate版本可能会使用默认的每表顺序。请测试您的版本,如果适用,请使用此版本而不是下面的版本。)


您需要更改映射以显式指定每个序列。这很烦人,重复且毫无意义。

@Entity@Table(name = "JUDGEMENTS")public class Judgement implements Serializable, Cloneable {    private static final long serialVersionUID = -7049957706738879274L;    @Id    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="judgements_id_seq")    @SequenceGenerator(name="judgements_id_seq", sequenceName="judgements_id_seq", allocationSize=1)    @Column(name = "JUD_ID")    private Long _judId;...

allocationSize=1
是非常重要的。如果您忽略它,Hibernate会盲目地假设序列是用定义的,
INCREMENT50
因此当它从序列中获取一个值时,它可以使用该值 及其下的49个值
作为唯一的生成键。如果您的数据库序列增加1(默认值),那么当Hibernate尝试重用现有密钥时,这将导致唯一违规。

请注意,一次获取一个密钥 导致每个插入的额外往返行程。据我所知,Hibernate无法

INSERT ...RETURNING
用于有效地返回生成的键,显然也不能使用JDBC生成的键接口。如果您告诉它使用序列,它将调用
nextval
来获取值,然后
insert
显式地获取该值,从而导致两次往返。为了减少开销,您可以在具有大量插入的键序列上设置更大的增量,记住要在映射
基础数据库序列上进行设置。这将导致Hibernate的调用
nextval
频率降低,并缓存键块以随其发送。

我敢肯定,从以上内容可以看出,我不同意这里所做的Hibernate设计选择,至少从与PostgreSQL一起使用的角度来看。它们应该使用

getGeneratedKeys
或使用
INSERT... RETURNING
with
DEFAULT
作为密钥,让数据库来处理此事,而Hibernate不必麻烦序列名称或对它们的显式访问。

顺便说一句,如果您将Hibernate与Pg一起使用,则可能还希望为Pg使用oplock触发器,以允许Hibernate的乐观锁定与普通数据库锁定安全地交互。没有它或类似的东西,您的Hibernate更新将倾向于破坏通过其他常规SQL客户端进行的更改。问我我怎么知道。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5124402.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-17
下一篇 2022-11-17

发表评论

登录后才能评论

评论列表(0条)

保存