Ошибка билда конфигурации хибернейта
От: aster.x  
Дата: 29.10.10 07:05
Оценка:
Доброе утро, уважаемые коллеги! Прошу помочь в запутанной ситуации.

Никак не могу выяснить причину глюка с маппингом в хибернейте. Время от времени приложения возникает такая ошибка:

[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.

Ошибка возникает не всегда, а при стечении каких-то обстоятельств, закономерности которых отследить пока не получилось. При этом сами по себе код и конфигурационные файлы рабочие — приложение как правило запускается и функционирует нормально, без ошибок.

Сталкивался кто-нибудь с подобными вещами?
Какие идеи есть, в чем может быть причина?
Re: Ошибка билда конфигурации хибернейта
От: aster.x  
Дата: 29.10.10 07:07
Оценка:
Дополнительные подробности:

Приложение — это веб-сервис, построенный на JWSDP. Хостится на Томкате 5.5.29. БД MySQL. Хибернейт версии 3.5.1. Среда разработки — IDEA 8.0.

Бизнес-логика приложения выделена в отдельную библиотеку (точнее, несколько библиотек). Ее уже юзает библиотека с классами и интерфейсами специфичными для веб-сервиса. Классы хибернейтовских сущностей и конфигурации маппинга — все определены в библиотеке с бизнес-логикой.

Код в среде разработки запускается нормально. То есть, когда выполняются вызовы непосредственно менеджеров бизнес-логики, все происходит нормально, никаких ошибок не возникает. Но стоит собрать веб-сервис, выложить его на Томкат и выполнить удаленный вызов процедуры веб-сервиса, как уже может вывалиться ошибка.

Но может и не вывалиться ведь! Причем ошибка происходит всегда на одном и том же классе! Который был сделан совсем давно, его маппинг давно не меняется, код этого класса и всех использующих его классов работает правильно, операции с таблицей, на которую маппится этот класс, выполняются правильно.

Но возникают какие-то непонятные обстоятельства, и начинается вываливаться эта ошибка. Причем ни сам класс, ни библиотека, в которой он находится, при этом не меняются!

Что за хрень такая творится!!!???
Re: Ошибка билда конфигурации хибернейта
От: Blazkowicz Россия  
Дата: 29.10.10 08:28
Оценка:
Здравствуйте, aster.x, Вы писали:

AX>Какие идеи есть, в чем может быть причина?

Настройте логирование классов hibernate на уровень debug. Смотрите лог, почему вдруг лишний класс попадает в список замапленых.
Re: Ошибка билда конфигурации хибернейта
От: aster.x  
Дата: 30.10.10 00:57
Оценка:
Решение нашлось, отпишу о результате.

Перетряхнул я насквозь исходники Хибернейта, и труды вознаградились!

Суть вся в том, что метод-геттер изначально объявлен в базовом классе сущности QuesitonnaireLocale, который есть generic, а возвращаемое значение геттера как раз определено с типом generic-параметра, на котором стоит констрейнт BaseLocaledEntity. Параметр-тип понижен рантаймом до констрейнта – с таким типом и предстал геттер пред очами хибернейта. Базовый класс непосредственно нигде, разумеется, не маппится, естественно и ошибка возникает.

Обойти проблему оказалось ну просто легчайше – достаточно при маппинге ассоциации атрибутом class указать нужный тип возвращаемого значения. Хибернейт в таком случае довольствуется только им и не бегает по иерархии наследования в поисках типа нужного возвращаемого значения свойства.

Но только вот истинные причины появления проблемы все же остались непонятными. И остались висеть в воздухе вопросы:
1. Почему хибернейт "пролетает" мимо геттера, переопределенного в реально используемом классе сущности, и достает геттер у базового класса?
2. Почему проблема проявляется только при запуске на Томкате, а при отладке через среду разработки все маппинги собираются без сбоев?
3. Почему даже при запуске на Томкате проблема возникает не регулярно, а только при каких-то определенных обстоятельствах?

Подчеркну, что проблема возникает не по вине сущностей, указанных в ошибке – код сущностей (и их базовых классов тоже) не меняется совершенно, маппинги не меняются, структура БД в части связанных с этими сущностями таблиц также не меняется.

Некоторые обстоятельства, связанные с появлением проблемы.

1. Замечено, что проблема появлялась при добавлении в проект библиотеки, в которой находились другие сущности вместе со своими маппингами.
2. Проблема появлялась также, когда в каком-то другом классе был геттер с тем же именем, что и один из геттеров в QuestionnaireLocale. Другой класс при этом совершенно произвольный, он мог быть вообще никак не связан ни с маппингами, ни с хибернейтом.

Последнее обстоятельство ну вообще чушь полная! Чертики там какие-то внутри сидят и бесстыдно бесятся!

Вот такие вот дела.

PS: Кстати, походу дела, пока в исходниках ковырялся, почерпнул для себя массу полезной информации об устройстве внутренних механизмов Хибернейта. Очччень полезное занятие оказалось, надо сказать.

Спасибо всем, кто потратил часть своего времени на эту проблему.

Если кому-то проблема покажется интересной, вот здесь показаны исходные код сущностей, их базовых классов и маппинги.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.