我让gwt应用程序在后端连接到postgres DB,一个java类"Decision"在DB中映射表"Decisions",当我试图将一个判断持久化到DB中时,它抛出了以下错误:

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)

我在DB中有一个序列名'judictions_id_seq'

有人能告诉我怎么了吗???谢谢

推荐答案

Hibernate的PostgreSQL语言不是很清晰.它不知道每个序列的情况,并且假设有一个全局数据库范围的序列叫做"hibernate_序列",它可以使用.


(UPDATE:如果指定了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定义的,因此当它从序列中获得一个值时,它可以使用该值and the 49 values below it作为唯一生成的键.如果数据库序列的增量为1(默认值),那么当Hibernatetry 重新使用现有密钥时,这将导致唯一的冲突.

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

我相信你可以从上面看到,我不同意这里所做的Hibernate设计 Select ,至少从与PostgreSQL一起使用的Angular 来看是这样的.他们应该使用getGeneratedKeysINSERT ... RETURNINGDEFAULT作为密钥,让数据库处理这个问题,而不用Hibernate为序列的名称或显式访问它们而麻烦自己.

顺便说一句,如果你在Pg中使用Hibernate,你可能还需要an oplock trigger for Pg来允许Hibernate的乐观锁定与正常的数据库锁定进行安全交互.如果没有它或类似的东西,您的Hibernate更新将倾向于 destruct 通过其他常规SQL客户机进行的更改.问我怎么知道的.

Postgresql相关问答推荐

Postgres SQL:获取列值在连续日期之间已更改的行

如何在postgres中测试锁定

select语句的Jooq代码生成

如何获取在 Go 中完成的 SQL 插入的错误详细信息?

PostgresQL:获取两个数组之间的对应数量

PostgreSQL - 继承表的常见自动增量

有对(type_id,element_id),如(1,1),(1,2),..(5,3).如果我需要获取没有 element_id 1 的类型 ID,如何从结果中排除 type_id?

我可以在 Ruby on Rails 上编写 PostgreSQL 函数吗?

PostgreSQL - 我应该如何使用 first_value()?

Rails:创建删除表级联迁移

!= 和 <> 运算符有什么区别?

带有 postgres 的 DOCKER 容器,警告:could not open statistics file "pg_stat_tmp/global.stat": Operation not permitted

Postgres 中的相似函数与 pg_trgm

Postgresql 中的 NOT EXISTS 子句

如何在 postgresql 交叉表中用零替换空值

使用 RPostgreSQL 写入特定模式

带有 WITH 子句的查询时出现 Postgresmissing FROM-clause entry错误

如何将 CSV 数据插入 PostgreSQL 数据库(远程数据库)

防止 PostgreSQL 中的递归触发器

pg_restore 目录错误