Hibernate:OneToMany 映射不基于 PK?

发布于 2024-09-11 00:00:34 字数 1203 浏览 5 评论 0原文

我有 2 个实体/表。

一个是一个适当的实体,我们称之为数据。它有许多包含所谓“多语言代码”的字段。

第二个表 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 集合?我需要我的大陆集合“代码表中的所有记录,其中代码=我的大陆代码属性的值”。或者也许有更合适的方式来表示这种关系?

注意:不幸的是我无法更改 SQL 模式...

I have 2 entities/tables.

One is a proper entity, let's call it data. It has a number of fields containing so-called "multilingual codes".

The second table, code, contains the multilingual values themselves.

Here is some example data :

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

I would like to map the properties continents, countries etc in the Data entity as a Map, like that :

@OneToMany()
@MapKey(name="languageCode")
private Map<String, Code> continents;

So that I can then read the text for the right language like that :

Data toto = dao.findByName("Toto");
String text = toto.getContries.get("FR").getText(); //--> returns "Suisse"
String text = toto.getContries.get("EN").getText(); //--> returns "Switzerland"

I also need to be able to make text search on the values of these "codes", using the language of the user. (e.g. get all datas where the country='suisse', in French !)

So, is it possible to map a OneToMany collection using a key field that is not the primary key of the current entity ? I need my continents collection "all records from the Code table where the code = the value of my continentCode property". Or maybe there is a more appropriate way of representing this kind of relationship ?

NB : Unfortunately I can't change the SQL schema...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

划一舟意中人 2024-09-18 00:00:34

好的,我找到了解决方案。我的数据实体上的 OneToMany 映射如下所示:

@OneToMany()
@JoinColumn(name="code", referencedColumnName="continentCode", insertable=false, updatable=false)   
@MapKey(name="languageCode")
private Map<String, AAGeoContinentThesaurusEntry> continents;

我还必须映射 ContinentalCode 列才能使其正常工作。我没有这样做,我得到了:

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() 

并收到字符串“Europe”:)

OK, I found the solution. The OneToMany mapping on my Data entity looks like that :

@OneToMany()
@JoinColumn(name="code", referencedColumnName="continentCode", insertable=false, updatable=false)   
@MapKey(name="languageCode")
private Map<String, AAGeoContinentThesaurusEntry> continents;

I also had to map the continentCode column in order for it to work. I fi didn't do it, I got a :

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)

Now I can do :

myData.getContinentCodes().get("FR").getText() 

and receive the string "Europe" :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文