Я пытаюсь выполнить вход в сеанс для объекта, который объявляет составной идентификатор без сопоставленного составного идентификатора.
Используемая версия Hibernate — 3.5.5.
Код выборки является универсальным и считывает объекты-контейнеры, упаковывая фактические данные:
ClassMetadata metadata =
session.getSessionFactory().getClassMetadata(wrapper.getDomainClass());
Serializable id = metadata.getIdentifier(wrapper, EntityMode.POJO);
return session.get(wrapper.getDomainClass(), id, LockOptions.UPGRADE);
Код ничего не знает о фактическом сопоставлении, поэтому ему приходится обращаться к метаданным об идентификаторе.
Если сопоставление определено как:
<hibernate-mapping default-access="field">
<class name="Wrapper"
entity-name="Data"
table="DATA">
<composite-id>
<key-property name="identifier" column="identifier" />
<key-property name="version" column="version" />
</composite-id>
<component name="domainObject" class="Data">
<property name="source" column="source" />
</component>
</class>
</hibernate-mapping>
без класса составного идентификатора id равен самому объекту и равен ссылке на оболочку.
Когда я делаю session.get() вместо извлечения объекта из базы данных, он возвращает тот же объект, который был передан в id (не равный объект, но тот же экземпляр объекта).
Обновление: На самом деле session.get() загружает объект из базы данных in
переданный объект id и возвращает его обратно. Я следил за тем, чтобы сначала подумал, что он пропускает загрузку.
Решение, которое я нашел до сих пор, заключается в том, чтобы ввести сопоставленный составной идентификатор и изменить сопоставление на:
<hibernate-mapping default-access="field">
<class name="Wrapper"
entity-name="Data1"
table="DATA_1">
<composite-id class="SurrogateKey" mapped="true">
<key-property name="identifier" column="identifier" />
<key-property name="version" column="version" />
</composite-id>
<component name="domainObject" class="Data">
<property name="source" column="source" />
</component>
</class>
</hibernate-mapping>
SurrogateKey определяется как объект с двумя полями и равенством/хэш-кодом по мере необходимости.
При этом идентификаторе изменения, возвращаемом metadata.getIdentifier(), является экземпляром SurrogateKey, а session.get() извлекает объект из базы данных, если он существует.
Проблема с исправлением сопоставления заключается в том, что имена свойств для критериев и HQL меняются с identifier на id.identifier, что на самом деле нарушает большую часть существующего кода.
Вещи, которые я изучаю в данный момент:
- Есть ли способ заставить session.get() работать без объявления класса Id (я знаю, что это не рекомендуется, но количество необходимых изменений может быть непомерно высоким)?
- Может ли альтернатива сказать hibernate обработать свойства как раньше, без добавления id. перед ними?
- Обновить спящий режим до версии 4 (нелегко из-за зависимых проектов и процесса утверждения)?
- Есть ли какие-либо другие варианты/обходные пути?
До сих пор мне удалось заставить работать только описанное выше решение, но я ищу менее навязчивое решение и буду признателен за любые подсказки, предложения, указатели на соответствующие документы.