Странное нарушение самореферентного ограничения после обновления 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 в классе без необходимости иметь дело с этим полем.)

Другие вопросы по тегам