Отобразить сложные объекты в Hibernate
Я уже задавал этот вопрос на форуме Hibernate, но думал, что задам его и здесь.
Я пытаюсь отобразить следующую модель, сохраняя семантику значений TranslatedText
а также Translation
объекты стоимости:
Оба значения как зависимые объекты
В идеале я бы карту TranslatedText
как <component>
в Question
а также Translation
как <bag>
из <composite-element>
в TranslatedText
,
Было бы просто сопоставить, если Question
ссылался только на один TranslatedText
, но так как он ссылается на два, мне нужен какой-то дискриминатор, основанный на имени свойства, содержащего значение (title
или же description
) для того, чтобы отобразить Translation
с иностранным ключом, состоящим из (question_id,property_name,language_code)
,
Одна из проблем заключается в том, что propertyName
не является частью модели и не должен, но я не нашел способа заставить Hibernate вставить значение, которое не исходит из модели.
Поэтому я попытался изменить модель и ввести специализированные Title
а также Description
классы, чтобы я имел type
там, что я мог бы использовать в качестве дискриминатора.
В конце это не очень помогло:
<component name="title" class="TranslatedText">
<bag name="translations" table="Translation">
<key>
<!-- PROBLEM: Could not find a way to create a custom join expression on question.id and question.title.type in here. -->
</key>
<composite-element class="Translation">
<!-- PROBLEM: Could not found a way to make Hibernate insert title.type from here, without having this value on the Translation object. -->
<property name="languageCode" type="string" column="language_code"/>
<property name="text" type="string"/>
</composite-element>
</bag>
</component>
Переведенный текст с <many-to-one>
Мне удалось получить что-то близкое к тому, что мне нужно, картируя TranslatedText
как сущность в Question
используя <many-to-one>
а затем карта Translation
как коллекция значений в TranslatedText
, но главная проблема с этим подходом заключается в том, что нет простого способа избавиться от сирот TranslatedText
а также Translation
, Я бы либо сделал это с помощью триггера БД или запланированного процесса.
Заключение
На данный момент у меня сложилось впечатление, что Hibernate недостаточно гибок, чтобы сопоставить исходную модель с надлежащей семантикой, но, надеюсь, я ошибаюсь, и есть способ сделать это.
1 ответ
Я не нашел способ отобразить их как значения. Однако следующее решение работает, и оно может быть полезно для вас. Я удалил TranslatedText
и связаны Question
непосредственно с коллекцией Translation
,
@Entity
public class Question {
@Id
private String id;
@JoinTable
@OrderColumn
@OneToMany(fetch = EAGER, cascade = ALL)
private List<Translation> titleTranslations;
@JoinTable
@OrderColumn
@OneToMany(fetch = EAGER, cascade = ALL)
private List<Translation> descriptionTranslations;
}
Недостаток здесь в том, что Translation
должен быть Entity
учебный класс.
@Entity
public class Translation {
@Id
private String id;
private String languageCode;
private String text;
}