postgresql 使用 @GeneratedValue 对 @Id 进行休眠空约束违反

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10661461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-20 23:55:38  来源:igfitidea点击:

Hibernate null constraint violation on @Id with @GeneratedValue

javahibernatepostgresqlannotationsplayframework

提问by Giuseppe Cardone

I am using Hibernate 4.1.3 (JPA) on the Play! framework. The database is PostgreSQL 8.4.2. The schema was generated using hibernate.hbm2ddl.auto="update".

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

Short version: I have a class that has an @Idfield that is a @GeneratedValue. Sometimes, when persisting it, I get a null-column violation, why?

简短版本:我有一个类,它的@Id字段是@GeneratedValue. 有时,在执行persist它时,我会遇到空列冲突,为什么?



More details:

更多细节:

I have a really simple class that I want to save to the database, that looks like this:

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

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

    @NotNull
    public String email;

    public Integer total;
}

I usually create an instance of MyObject, I assign a value to emailand totalfields while idis null and I save it via EntityManager.persist(). Hibernate gets an id for the new object and saves it to the DB.

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

However sometimes, I get the following stacktrace:

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

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$$anon: Execution exception [[PersistenceException: org.hibernate.exception.ConstraintViolationException: ERROR: null value in column "id" violates not-null constraint]]

How is this possible? How can I track down the problem?

这怎么可能?如何追踪问题?

Here's the relevant DDL generated by Hibernate:

下面是 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);

采纳答案by Matt

Try the annotation @org.hibernate.annotations.GenericGenerator(name = “test-hilo-strategy”, strategy = “hilo”):

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

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

As someone noted above, AUTOdoes not do what you think. It uses the underlying DB to determine how to generate values. It may pick sequences (for oracle), identity column (for mssql), or something else that is db specific.

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

The approach here uses an internal strategy that Hibernate supplies called "hilo".

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

See chapter 5 of the Hibernate reference manual dealing with "Generator" for a full description of what each of the supplied ones does.

请参阅 Hibernate 参考手册中关于“生成器”的第 5 章,了解每个提供的生成器的功能的完整描述。

回答by bluish

Neither the OP solution nor Matt's solution worked with my PostgreSQL 9.3.

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

But this one works:

但是这个有效:

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

Replace mytable_id_seqwith the name of the sequence that generates your id.

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

回答by Vinit Bhardwaj

Use Hibernate method:- save(String entityName, Object object) Persist the given transient instance, first assigning a generated identifier.

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

Do not use :- @GeneratedValue(strategy=GenerationType.IDENTITY) for primary key if you want to persist user define Id.

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

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

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

回答by AConsumer

In mycase i was using Identitygeneration strategy and i have set the wrong data type in Postgres. Following steps i performed to debug the problem.

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

set

spring.jpa.hibernate.ddl-auto=update

spring.jpa.show-sql=truein application.properties and Drop the tables.

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

By this hibernate will automatically create the schema for you on the basis of your data-type.I noticed change in the datatype of id field.

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

Now when i tried any post requests, everything worked fine.

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