I'm using hibernate-entitymanager
in a Spring application. I'm in the process of upgrading my Hibernate version. Narrowed it down to the exact version: when I upgrade from 4.2.1.Final to 4.2.2.Final (or anything higher than that), I'm getting the following error when my unit tests starts up and try to create the database schema:
2014-03-02 18:02:51,559 ERROR [SchemaExport] [main] HHH000389: Unsuccessful: alter table Incident add constraint FK_d91dua6gkdp1jn826adqss3aq foreign key (uuid) references Incident
2014-03-02 18:02:51,559 ERROR [SchemaExport] [main] Constraint "FK_D91DUA6GKDP1JN826ADQSS3AQ" already exists; SQL statement:
alter table Incident
add constraint FK_d91dua6gkdp1jn826adqss3aq
foreign key (uuid)
references Incident [90045-170]
The error does not prevent the system from working just fine, but clearly I can't go to production with such a nasty error in my system and no explanation of it.
This looks a lot like the Incident
table has a foreign key relationship to itself, which is absolutely not the case.
I'll try to copy the essence here of the Incident
entity:
@Entity
@Audited
@EntityListeners(value = {IncidentIdentifierPrePersistListener.class })
@FilterDefs( ... )
@Filters( ... )
public class Incident extends SomeBaseClass {
@Id
private String uuid = UUID.randomUUID().toString();
@Column(nullable = false, unique = true)
private long identifier;
... a bunch more fields ...
}
Please let me know if I can provide anything else to help ya'all to shed a light on this. I've played around with it for hours, fruitless, and your help would be much appreciated.
Here is what happened:
Incident
defined a @ManyToOne
to an entity Project
Project
incorrectly defined a @ManyToMany
back to the entity Incident
(should have been a @OneToMany
)As a result Hibernate generated the awkward following constraint:
CONSTRAINT fk909a8f241708a1e FOREIGN KEY (uuid)
REFERENCES incident (uuid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
Incident
inherits SomeBaseClass
which has @Inheritance(strategy = InheritanceType.JOINED)
As a result Hibernate generated the following constraint:
CONSTRAINT fk909a8f2ddd08e84 FOREIGN KEY (uuid)
REFERENCES somebaseclass (uuid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
As a result of HHH-8217 (Make generated constraint names short and non-random) in Hibernate 4.2.2 the above two constraint definitions suddenly got the same name (Hibernate did only consider the entity and the columns of the foreign key constraint, not the target entity of the foreign key; note how generateName
only takes one Table
as a parameter)
Constraint ... already exists
Changing the @ManyToMany
to @OneToMany
fixes this entirely.
By the way, the offending field definition (the one with the @ManyToMany
) also previously caused me problems with Hibernate Envers' @Audited
, the reason of which I never understood, and that got resolved now as well. It's a good day. (Not sure if @Audited
means much for a mapped field, but at least I can have @Audited
on the class without needing to deal with this field.)