Hibernar:¿El mapeo OneToMany no se basa en PK?
-
26-09-2020 - |
Pregunta
Tengo 2 entidades/tablas.
Uno es una entidad propia, llamémosla data
.Tiene una serie de campos que contienen los llamados "códigos multilingües".
La segunda mesa, code
, contiene los valores multilingües mismos.
Aquí hay algunos datos de ejemplo:
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
Me gustaría mapear las propiedades, continentes, países, etc. en la entidad de datos como un mapa, así:
@OneToMany()
@MapKey(name="languageCode")
private Map<String, Code> continents;
Para luego poder leer el texto en el idioma correcto así:
Data toto = dao.findByName("Toto");
String text = toto.getContries.get("FR").getText(); //--> returns "Suisse"
String text = toto.getContries.get("EN").getText(); //--> returns "Switzerland"
También necesito poder realizar búsquedas de texto sobre los valores de estos "códigos", utilizando el idioma del usuario.(p.ej.obtener todos los datos donde el país = 'suisse', en francés!)
Entonces, ¿es posible mapear una OneToMany
colección utilizando un campo clave que no es la clave principal de la entidad actual?Necesito mi colección de continentes "todos los registros de la tabla de códigos donde el código = el valor de mi continentCode
propiedad".¿O tal vez exista una forma más apropiada de representar este tipo de relación?
Nota:Lamentablemente no puedo cambiar el esquema SQL...
Solución
Bien, encontré la solución.El mapeo OneToMany en mi entidad de datos se ve así:
@OneToMany()
@JoinColumn(name="code", referencedColumnName="continentCode", insertable=false, updatable=false)
@MapKey(name="languageCode")
private Map<String, AAGeoContinentThesaurusEntry> continents;
También tuve que mapear la columna continenteCode para que funcionara.No lo hice, obtuve un:
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)
Ahora puedo hacer:
myData.getContinentCodes().get("FR").getText()
y recibir la cadena "Europa" :)