7

我在 Play 上使用 Hibernate 4.1.3 (JPA)!框架。数据库是 PostgreSQL 8.4.2。架构是使用生成的hibernate.hbm2ddl.auto="update"

简短版本:我有一个类,它的@Id字段是@GeneratedValue. 有时,当persist我使用它时,我得到一个空列违规,为什么?


更多细节:

我有一个非常简单的类,我想将其保存到数据库中,如下所示:

@Entity
class MyObject {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;

    @NotNull
    public String email;

    public Integer total;
}

我通常创建一个 MyObject 的实例,在为 null时为emailtotal字段分配一个值,然后通过. Hibernate 获取新对象的 id 并将其保存到数据库。idEntityManager.persist()

但是有时,我会得到以下堆栈跟踪:

2012-05-19 00:45:16,335 - [ERROR] - from org.hibernate.engine.jdbc.spi.SqlExceptionHelper [SqlExceptionHelper.java:144] in play-akka.actor.actions-dispatcher-6 
ERROR: null value in column "id" violates not-null constraint

2012-05-19 00:45:16,350 - [ERROR] - from application in play-akka.actor.actions-dispatcher-6 


! @6ad7j3p8p - Internal server error, for request [POST /method] ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[PersistenceException: org.hibernate.exception.ConstraintViolationException: ERROR: null value in column "id" violates not-null constraint]]

这怎么可能?我怎样才能找到问题?

下面是 Hibernate 生成的相关 DDL:

CREATE TABLE myobject (
    id bigint NOT NULL,
    email character varying(255) NOT NULL,
    physical integer
);

CREATE SEQUENCE hibernate_sequence
    START WITH 1
    INCREMENT BY 1
    NO MAXVALUE
    NO MINVALUE
    CACHE 1;


ALTER TABLE ONLY dailydetailedscore
    ADD CONSTRAINT dailydetailedscore_pkey PRIMARY KEY (id);
4

4 回答 4

3

尝试注释@org.hibernate.annotations.GenericGenerator(name = “test-hilo-strategy”, strategy = “hilo”)

@Id
@org.hibernate.annotations.GenericGenerator(name=“hilo-strategy”, strategy = “hilo”)
@GeneratedValue(generator = ”hilo-strategy”)

正如上面有人指出的那样,AUTO不会按照您的想法行事。它使用底层数据库来确定如何生成值。它可以选择序列(对于 oracle)、标识列(对于 mssql)或其他特定于 db 的内容。

这里的方法使用 Hibernate 提供的称为“hilo”的内部策略。

请参阅 Hibernate 参考手册的第 5 章处理“生成器”,以完整描述每个提供的生成器的作用。

于 2012-05-19T05:38:05.590 回答
2

OP 解决方案和 Matt 的解决方案都不适用于我的 PostgreSQL 9.3。

但这一个有效:

@SequenceGenerator(name="identifier", sequenceName="mytable_id_seq", allocationSize=1)  
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="identifier")

替换mytable_id_seq为生成您的 id 的序列的名称。

于 2014-12-04T09:59:13.317 回答
0

使用 Hibernate 方法:- save(String entityName, Object object) 持久化给定的瞬态实例,首先分配一个生成的标识符。

如果要保留用户定义的 Id,请不要使用 :- @GeneratedValue(strategy=GenerationType.IDENTITY) 作为主键

详情:- http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/Session.html#save(java.lang.String

于 2017-01-22T07:51:52.290 回答
0

在我的情况下,我使用了身份生成策略,并且在 Postgres 中设置了错误的数据类型。按照我执行的步骤来调试问题。

spring.jpa.hibernate.ddl-auto=update

spring.jpa.show-sql=true在 application.properties 中并删除表。

通过这个休眠将根据您的数据类型自动为您创建模式。我注意到 id 字段的数据类型发生了变化。

现在,当我尝试任何发布请求时,一切正常。

于 2019-05-06T06:39:38.697 回答