Спящий режим:Сопоставление OneToMany не на основе PK?
-
26-09-2020 - |
Вопрос
У меня есть 2 объекта/таблицы.
Один из них — это настоящая сущность, назовем ее data
.Он имеет ряд полей, содержащих так называемые «многоязычные коды».
Второй стол, code
, содержит сами многоязычные значения.
Вот пример данных:
Data table
id name continentCode countryCode
------------------------------------
1 Toto EU CH
2 Titi AS CN
Code table
id code language text
----------------------------
1 EU EN Europe
2 EU FR Europe
3 EU DE Europa
4 CH EN Switzerland
5 CH FR Suisse
6 CH DE Schweiz
... etc
Я хотел бы сопоставить свойства континентов, стран и т. д. в объекте данных как карту, например:
@OneToMany()
@MapKey(name="languageCode")
private Map<String, Code> continents;
Чтобы я мог затем прочитать текст на нужном языке следующим образом:
Data toto = dao.findByName("Toto");
String text = toto.getContries.get("FR").getText(); //--> returns "Suisse"
String text = toto.getContries.get("EN").getText(); //--> returns "Switzerland"
Мне также нужно иметь возможность осуществлять текстовый поиск по значениям этих «кодов», используя язык пользователя.(например.получить все данные, где страна = 'suisse', на французском языке!)
Итак, можно ли составить карту OneToMany
сбор с использованием ключевого поля, которое не является первичным ключом текущего объекта?Мне нужна моя коллекция континентов "все записи из таблицы кодов, где код = значение моего continentCode
свойство".Или, может быть, есть более подходящий способ представления такого рода отношений?
Примечание:К сожалению, я не могу изменить схему SQL...
Решение
Хорошо, я нашел решение.Сопоставление OneToMany с моим объектом данных выглядит следующим образом:
@OneToMany()
@JoinColumn(name="code", referencedColumnName="continentCode", insertable=false, updatable=false)
@MapKey(name="languageCode")
private Map<String, AAGeoContinentThesaurusEntry> continents;
Мне также пришлось сопоставить столбец ContainerCode, чтобы он работал.Я этого не делал, у меня есть:
org.hibernate.MappingException: Unable to find column with logical name: GCH_CDE_CODE_CNT in org.hibernate.mapping.Table
(GCHDATA) and its related supertables and secondary tables
at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:396)
at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:102)
Теперь я могу сделать:
myData.getContinentCodes().get("FR").getText()
и получаем строку "Европа" :)