Странное нарушение самореферентного ограничения после обновления Hibernate
Я использую hibernate-entitymanager
в приложении Spring. Я в процессе обновления моей версии Hibernate. Сузил до точной версии: когда я обновляюсь с 4.2.1.Final до 4.2.2.Final (или чего-то более высокого), я получаю следующую ошибку, когда мои модульные тесты запускаются и пытаются создать базу данных схема:
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]
Ошибка не мешает системе работать нормально, но, очевидно, я не могу перейти к производству с такой неприятной ошибкой в моей системе и без объяснения причин.
Это очень похоже на Incident
Таблица имеет отношение внешнего ключа к себе, что совершенно не так.
Я постараюсь скопировать суть здесь Incident
юридическое лицо:
@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 ...
}
Пожалуйста, дайте мне знать, если я могу предоставить что-нибудь еще, чтобы помочь вам пролить свет на это. Я играл с ним часами, безрезультатно, и ваша помощь будет высоко ценится.
1 ответ
Вот что случилось:
Incident
определил@ManyToOne
к сущностиProject
Project
неправильно определен@ManyToMany
вернуться к сущностиIncident
(должен был быть@OneToMany
)В результате Hibernate сгенерировал неловкое следующее ограничение:
CONSTRAINT fk909a8f241708a1e FOREIGN KEY (uuid) REFERENCES incident (uuid) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION
Incident
наследуетсяSomeBaseClass
у которого есть@Inheritance(strategy = InheritanceType.JOINED)
В результате Hibernate сгенерировал следующее ограничение:
CONSTRAINT fk909a8f2ddd08e84 FOREIGN KEY (uuid) REFERENCES somebaseclass (uuid) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION
В результате HHH-8217 (сделать сгенерированные имена ограничений короткими и неслучайными) в Hibernate 4.2.2 два приведенных выше определения ограничений неожиданно получили одно и то же имя (Hibernate рассматривал только сущность и столбцы ограничения внешнего ключа, но не целевой объект внешнего ключа; обратите внимание, как
generateName
только занимает одинTable
как параметр)- И произошло соответствующее столкновение:
Constraint ... already exists
Изменение @ManyToMany
в @OneToMany
исправляет это полностью.
Кстати, оскорбительное определение поля (с @ManyToMany
) также ранее вызывал у меня проблемы с Hibernate Envers ' @Audited
причину, о которой я никогда не понимал, и которая стала решаться и сейчас. Это хороший день. (Не уверен если @Audited
много значит для отображенного поля, но, по крайней мере, я могу иметь @Audited
в классе без необходимости иметь дело с этим полем.)