gpt4 book ai didi

hibernate 无法获取下一个序列值

转载 作者:行者123 更新时间:2023-11-29 11:06:15 28 4
gpt4 key购买 nike

我有 gwt 应用程序连接到后端的 postgres 数据库,并且有一个 java 类“判断”映射数据库中的表“判断”,当我试图将判断持久化到数据库中时,它抛出了以下错误:

Caused by: org.hibernate.exception.SQLGrammarException: could not get next sequence value
...
Caused by: org.postgresql.util.PSQLException: ERROR: relation "hibernate_sequence" does not exist

我的判断类是这样的

@Entity
@Table(name = "JUDGEMENTS")
public class Judgement implements Serializable, Cloneable {

private static final long serialVersionUID = -7049957706738879274L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "JUD_ID")
private Long _judId;
...

而我的表判断是:

   Column    |            Type             |                        Modifiers                        
-------------+-----------------------------+---------------------------------------------------------
jud_id | bigint | not null default nextval('judgements_id_seq'::regclass)
rating | character varying(255) |
last_update | timestamp without time zone |
user_id | character varying(255) |
id | integer |
Indexes:
"judgements_pkey" PRIMARY KEY, btree (jud_id)
Foreign-key constraints:
"judgements_id_fkey" FOREIGN KEY (id) REFERENCES recommendations(id)
"judgements_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(user_id)

我在数据库中有一个序列名称“judgements_id_seq”

谁能告诉我这是怎么回事???谢谢。

最佳答案

Hibernate 的 PostgreSQL 方言不是很聪明。它不知道您的 per-SERIAL 序列,并假设存在一个它可以使用的名为“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 将盲目地假定该序列是用 INCREMENT 50 定义的,因此当它从序列中获取一个值时,它可以使用该值和它下面的 49 个值 作为唯一生成的 key 。如果您的数据库序列递增 1(默认值),那么这将导致唯一违规,因为 Hibernate 会尝试重新使用现有键。

请注意,一次获取一个 key 导致每次插入额外的往返。据我所知,Hibernate 无法使用 INSERT ... RETURNING 有效地返回生成的 key ,它显然也不能使用 JDBC 生成的 key 接口(interface)。如果您告诉它使用一个序列,它会调用 nextval 来获取值,然后显式地insert,从而产生两次往返。为了降低成本,您可以在具有大量插入的键序列上设置更大的增量,记住在映射底层数据库序列上设置它。这将导致 Hibernate 调用 nextval 的频率降低,并缓存 key block 以在运行时分发。

我相信您可以从上面看出我不同意这里做出的 Hibernate 设计选择,至少从将它与 PostgreSQL 一起使用的角度来看是这样。他们应该使用 getGeneratedKeys 或使用 INSERT ... RETURNINGDEFAULT 作为键,让数据库处理这个而 Hibernate 不必为序列的名称或对它们的显式访问而烦恼。

顺便说一句,如果您将 Hibernate 与 Pg 一起使用,您可能还需要 an oplock trigger for Pg允许 Hibernate 的乐观锁定与普通数据库锁定安全交互。没有它或类似的东西,您的 Hibernate 更新将倾向于破坏通过其他常规 SQL 客户端所做的更改。问我怎么知道。

关于 hibernate 无法获取下一个序列值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10628099/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com