hibernate无法获取下一个序列值

我有gwt应用程序连接到后端的postgres DB和一个java类’判断’映射DB中的表’判断’,当我试图持久判断到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中有一个SEQUENCE名称’judgements_id_seq’

任何人都可以告诉我什么问题?谢谢。

Hibernate的PostgreSQL方言不是很明亮。它不知道你的每个SERIAL序列,并且假设有一个称为“hibernate_sequence”的全局数据库范围序列,它可以使用。

(更新:似乎较新的Hibernate版本可能使用默认的每表序列当GenerationType.IDENTITY被指定时测试您的版本,并使用这个而不是下面如果它适用于你。)

您需要更改映射以明确指定每个序列。这是恼人,重复和无意义。

@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个值作为唯一生成的键。如果您的数据库序列递增1 – 默认值 – 那么这将导致唯一的违例,因为Hibernate尝试重新使用现有键。

注意,一次获取一个键将导致每次插入一个额外的往返行程。至于我可以告诉Hibernate不能使用INSERT … RETURNING有效地返回生成的密钥,也不能显然使用JDBC生成的密钥接口。如果你告诉它使用一个序列,它会调用nextval获取值,然后显式插入,导致两次往返。为了降低成本,您可以对具有大量插入的键序列设置更大的增量,记住在映射和基础数据库序列上设置它。这将导致Hibernate不太频繁地调用nextval,并缓存块的密钥,以便随时发布。

我相信你可以从上面看到,我不同意Hibernate的设计选择这里,至少从使用PostgreSQL的角度。他们应该使用getGeneratedKeys或使用INSERT … RETURNING与DEFAULT作为键,让数据库处理这个,而Hibernate不必麻烦自己的序列名称或显式访问它们。

BTW,如果你使用Hibernate与Pg,你可能也希望an oplock trigger for Pg允许Hibernate的乐观锁定与正常的数据库锁定安全交互。没有它或类似的东西,你的Hibernate更新将倾向于通过其他常规SQL客户端进行修改更改。问我怎么知道。

http://stackoverflow.com/questions/10628099/hibernate-could-not-get-next-sequence-value

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:hibernate无法获取下一个序列值