use*_*587 44 postgresql hibernate
我有gwt应用程序连接到后端的postgres DB,以及一个java类'判断'映射数据库中的表'判断',当我试图将判断持久化到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
Run Code Online (Sandbox Code Playgroud)
我的审判级看起来像这样
@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;
...
Run Code Online (Sandbox Code Playgroud)
我的表判断是:
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)
Run Code Online (Sandbox Code Playgroud)
我在DB中有一个SEQUENCE名称'judgements_id_seq'
任何人都可以告诉我什么是错的??? 谢谢.
Cra*_*ger 82
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;
...
Run Code Online (Sandbox Code Playgroud)
这allocationSize=1非常重要.如果省略它,Hibernate将盲目地假设序列是定义的,INCREMENT 50因此当它从序列中获取值时,它可以使用该值并将其下面的49个值作为唯一生成的键.如果您的数据库序列增加1(默认值),那么当Hibernate尝试重用现有密钥时,这将导致唯一的违规.
请注意,一次获得一个密钥将导致每个插入一次额外的往返.据我所知,Hibernate无法INSERT ... RETURNING有效地返回生成的密钥,也无法使用JDBC生成的密钥接口.如果你告诉它使用一个序列,那么它将调用nextval以获得insert明确的值,从而导致两次往返.为了降低成本,可以在具有大量插入的键序列上设置更大的增量,记住在映射和底层数据库序列上设置它.这将导致Hibernate nextval更频繁地调用并缓存密钥块,以便随时分发.
我相信你可以从上面看到我不同意这里做的Hibernate设计选择,至少从与PostgreSQL一起使用它的角度来看.他们应该使用getGeneratedKeys或使用INSERT ... RETURNING与DEFAULT为重点,让数据库照顾这个,而不必麻烦休眠其在序列或给他们明确的访问的名称自我.
顺便说一句,如果你正在使用Pg的Hibernate,你可能还需要一个用于Pg的oplock触发器,以允许Hibernate的乐观锁定与正常的数据库锁定安全地交互.没有它或类似的东西,你的Hibernate更新将倾向于破坏通过其他常规SQL客户端所做的更改.问我怎么知道.
小智 44
我似乎记得必须使用@GeneratedValue(strategy = GenerationType.IDENTITY)让Hibernate在PostgreSQL上使用'serial'列.
小智 12
您需要使用策略GenerationType.IDENTITY而不是GenerationType.AUTO设置@GeneratedId列
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "JUD_ID")
private Long _judId;
Run Code Online (Sandbox Code Playgroud)
spl*_*dli 10
我以前遇到同样的错误,在你的数据库中输入这个查询 CREATE SEQUENCE hibernate_sequence START WITH 1 INCREMENT BY 1 NOCYCLE;
这对我有用,祝你好运〜
| 归档时间: |
|
| 查看次数: |
93166 次 |
| 最近记录: |