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);
Try the annotation
@org.hibernate.annotations.GenericGenerator(name = “test-hilo-strategy”, strategy = “hilo”):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.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.