Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate null constraint violation on @Id with @GeneratedValue

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".

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


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 email and total fields while id is null and I save it via EntityManager.persist(). Hibernate gets an id for the new object and saves it to the DB.

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$1$$anon$1: 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:

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);
like image 776
Giuseppe Cardone Avatar asked May 19 '12 00:05

Giuseppe Cardone


People also ask

What does the @ID annotation do?

The @Id annotation is inherited from javax.persistence.Id, indicating the member field below is the primary key of the current entity. Hence your Hibernate and spring framework as well as you can do some reflect works based on this annotation.

What is @ID in hibernate?

The most straightforward way to define an identifier is by using the @Id annotation. Simple ids are mapped using @Id to a single property of one of these types: Java primitive and primitive wrapper types, String, Date, BigDecimal and BigInteger.

What is @GeneratedValue annotation in spring boot?

You can change that by referencing the name of a @SequenceGenerator in the generator attribute of the @GeneratedValue annotation. The @SequenceGenerator annotation lets you define the name of the generator, the name, and schema of the database sequence and the allocation size of the sequence.

What is @GeneratedValue strategy GenerationType Auto?

GenerationType. AUTO This GenerationType indicates that the persistence provider should automatically pick an appropriate strategy for the particular database. This is the default GenerationType, i.e. if we just use @GeneratedValue annotation then this value of GenerationType will be used.


1 Answers

Try the annotation @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, AUTO does 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.

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

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

like image 51
Matt Avatar answered Sep 30 '22 06:09

Matt