Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate not respecting MySQL auto_increment primary key field

I am trying to learn how Hibernate works, and I am running into an almost unacceptable learning curve. I can't see how to get Hibernate to respect the auto_increment policy for my objects. Instead, it is overwriting entries in the database with existing IDs, beginning with 1.

I have a simple Foo object, backed by a MySQL table defined like this:

CREATE TABLE `Foo` (
  `fooId` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`fooId`),
)

I have confirmed that inserting multiple Foo objects by hand with SQL (insert into Foo values();) does the right thing.

My Java class has the ID specified using annotations like this:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="fooId")
private Integer id;

I then execute some test code that simply instantiates Foo objects and saves them to the database (using session.save(obj)). It seems that it uses its own primary key sequence, beginning with one, and does not look at the table's key policy. It overwrites whatever was there.

I have tried variations on the @GeneratedValue bit (using all possible strategies, leaving off the parenthetic clause). Somebody even suggested leaving off the GeneratedValue entirely. Nothing seems to work.

Am I leaving something out? What am I missing? Is Hibernate really this hard?

(If anybody has an alternative Java database persistence option, please suggest one. I am making prototypes, not long-lasting mondo-engineered projects.)

like image 848
Gabe Johnson Avatar asked Feb 24 '09 16:02

Gabe Johnson


People also ask

Can a primary key be AUTO_INCREMENT?

Auto-increment allows a unique number to be generated automatically when a new record is inserted into a table. Often this is the primary key field that we would like to be created automatically every time a new record is inserted.

How auto increment is primary key in Hibernate?

If you want to use this strategy, you have to annotate the primary key attribute @Id and with the @GeneratedValue annotation and set the strategy attribute to GenerationType. IDENTITY. If you now persist a new Author entity, Hibernate will use the auto-incremented database column to generate the primary key value.

Does MySQL auto increment primary key?

One of the important tasks while creating a table is setting the Primary Key. The Auto Increment feature allows you to set the MySQL Auto Increment Primary Key field. This automatically generates a sequence of unique numbers whenever a new row of data is inserted into the table.

Is primary key auto increment by default?

No. A primary key must be unique and that has to be 100% guaranteed, and NON NULL A primary key should be stable if ever possible and not change.


4 Answers

I believe you want GenerationType.IDENTITY. MySql does not use a table or sequence for generating the Id value.

like image 133
Clint Avatar answered Sep 18 '22 11:09

Clint


I wrote this in a comment under the accepted answer, but those aren't shown by default so I'll re-post it as an answer.

I was using a hibernate.cfg.xml file off some dude's web site, and it had this:

<property name="hibernate.hbm2ddl.auto">create</property> 

This made the system to re-create my table each time I ran my app. Commenting it out solved the problem.

The other two answers about the various ways to create IDs are correct. My original problem's symptom seemed to do with ID generation, but the actual cause was misconfiguration.

like image 41
Gabe Johnson Avatar answered Sep 18 '22 11:09

Gabe Johnson


I think GenerationType.AUTO is right as is <id ...><generator class="native" /></id>

Picks an appropriate strategy for the particular database.

http://www.hibernate.org/hib_docs/ejb3-api/javax/persistence/GenerationType.html

http://www.hibernate.org/hib_docs/reference/en/html/mapping.html

like image 24
cherouvim Avatar answered Sep 18 '22 11:09

cherouvim


I use the following with auto_increment, works perfectly:

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "db_id", unique = true, nullable = false)
public Long getDbId() {
    return this.dbId;
}

public void setDbId(Long dbId) {
    this.dbId = dbId;
}
like image 28
Piko Avatar answered Sep 19 '22 11:09

Piko