From the community documentation:
hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.
e.g. validate | update | create | create-drop
So the list of possible options are,
- validate: validate the schema, makes no changes to the database.
- update: update the schema.
- create: creates the schema, destroying previous data.
- create-drop: drop the schema when the SessionFactory is closed explicitly, typically when the application is stopped.
- none: does nothing with the schema, makes no changes to the database
These options seem intended to be developers tools and not to facilitate any production level databases, you may want to have a look at the following question; Hibernate: hbm2ddl.auto=update in production?
Your mapping is totally valid and works with EclipseLink as JPA 2.0 implementation (without the Fetch
annotation of course), but indeed fails with Hibernate.
Here is the DDL with Hibernate:
create table foo_bar_map (foo_id bigint not null, bar_id bigint not null, order_index integer not null, primary key (foo_id, order_index), unique (bar_id))
alter table foo_bar_map add constraint FK14F1CB7FA042E82 foreign key (bar_id) references Bar4022509
alter table foo_bar_map add constraint FK14F1CB7B6DBCCDC foreign key (foo_id) references Foo4022509
So let's say Foo#1
holds a list with Bar#1
, Bar#2
, Bar#3
, the join table contains:
foo_id | bar_id | order_index
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
When removing, say the first item from the list, Hibernate first delete
the last row (WTF?) from the join table:
foo_id | bar_id | order_index
1 | 1 | 1
1 | 2 | 2
And then tries to update
the bar_id
column in the join table instead of the order_index
(WTF!?) to reflect the "new" ordering of the items in the list. First (schematically):
foo_id | bar_id | order_index
1 | 2 | 1
1 | 2 | 2
where the next step would result in:
foo_id | bar_id | order_index
1 | 2 | 1
1 | 3 | 2
Obviously, this approach doesn't sound right and doesn't work because of the unique
constraint on bar_id
. More generally, why the hell does Hibernate mess with the bar_id
instead of updating the order_index
column?
I consider this to be an Hibernate bug (reported as HHH-5694, see HHH-1268 now).
Best Answer
Just dealt with this exact issue. You're thinking in tables, not objects. Just reference
tags.name
and let Hibernate take care of the rest:If you watch the SQL Hibernate spits out, you'll see it uses the join table.