Доброе утро, уважаемые коллеги! Прошу помочь в запутанной ситуации.
Никак не могу выяснить причину глюка с маппингом в хибернейте. Время от времени приложения возникает такая ошибка:
[Type:class org.hibernate.MappingException]
[Message:An association from the table МОЯ_ТАБЛИЦА refers to an unmapped class: МОЙ_КЛАСС]
Stack:
org.hibernate.cfg.Configuration.secondPassCompileForeignKeys() at line 1343.
org.hibernate.cfg.Configuration.secondPassCompile() at line 1261.
org.hibernate.cfg.Configuration.buildSessionFactory() at line 1377.
Ошибка возникает не всегда, а при стечении каких-то обстоятельств, закономерности которых отследить пока не получилось. При этом сами по себе код и конфигурационные файлы рабочие — приложение как правило запускается и функционирует нормально, без ошибок.
Сталкивался кто-нибудь с подобными вещами?
Какие идеи есть, в чем может быть причина?
Решение нашлось, отпишу о результате.
Перетряхнул я насквозь исходники Хибернейта, и труды вознаградились!
Суть вся в том, что метод-геттер изначально объявлен в базовом классе сущности QuesitonnaireLocale, который есть generic, а возвращаемое значение геттера как раз определено с типом generic-параметра, на котором стоит констрейнт BaseLocaledEntity. Параметр-тип понижен рантаймом до констрейнта – с таким типом и предстал геттер пред очами хибернейта. Базовый класс непосредственно нигде, разумеется, не маппится, естественно и ошибка возникает.
Обойти проблему оказалось ну просто легчайше – достаточно при маппинге ассоциации атрибутом class указать нужный тип возвращаемого значения. Хибернейт в таком случае довольствуется только им и не бегает по иерархии наследования в поисках типа нужного возвращаемого значения свойства.
Но только вот истинные причины появления проблемы все же остались непонятными. И остались висеть в воздухе вопросы:
1. Почему хибернейт "пролетает" мимо геттера, переопределенного в реально используемом классе сущности, и достает геттер у базового класса?
2. Почему проблема проявляется только при запуске на Томкате, а при отладке через среду разработки все маппинги собираются без сбоев?
3. Почему даже при запуске на Томкате проблема возникает не регулярно, а только при каких-то определенных обстоятельствах?
Подчеркну, что проблема возникает не по вине сущностей, указанных в ошибке – код сущностей (и их базовых классов тоже) не меняется совершенно, маппинги не меняются, структура БД в части связанных с этими сущностями таблиц также не меняется.
Некоторые обстоятельства, связанные с появлением проблемы.
1. Замечено, что проблема появлялась при добавлении в проект библиотеки, в которой находились другие сущности вместе со своими маппингами.
2. Проблема появлялась также, когда в каком-то другом классе был геттер с тем же именем, что и один из геттеров в QuestionnaireLocale. Другой класс при этом совершенно произвольный, он мог быть вообще никак не связан ни с маппингами, ни с хибернейтом.
Последнее обстоятельство ну вообще чушь полная! Чертики там какие-то внутри сидят и бесстыдно бесятся!
Вот такие вот дела.
PS: Кстати, походу дела, пока в исходниках ковырялся, почерпнул для себя массу полезной информации об устройстве внутренних механизмов Хибернейта. Очччень полезное занятие оказалось, надо сказать.
Спасибо всем, кто потратил часть своего времени на эту проблему.
Если кому-то проблема покажется интересной, вот
здесь показаны исходные код сущностей, их базовых классов и маппинги.