java JPA - @OneToMany 作为地图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11789649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:22:03  来源:igfitidea点击:

JPA - @OneToMany as a Map

javajpamapone-to-many

提问by dnc253

This seems like a common enough case, but as JPA newbie, I am having trouble figuring this out. I'm using EclipseLink and PostgreSQL, but this should relate to just the JPA spec.

这似乎是一个足够常见的案例,但作为 JPA 新手,我无法弄清楚这一点。我正在使用 EclipseLink 和 PostgreSQL,但这应该只与 JPA 规范有关。

I have one table PRIMARYthat has an ID and then a bunch of other columns. There is another table SECONDARYthat has a foreign key into the PRIMARYtable also called ID. This SECONDARYtable has a composite key of that IDand a varchar representing a locale.

我有一个表PRIMARY,它有一个 ID,然后是一堆其他列。还有另一个表SECONDARY,该PRIMARY表有一个外键,也称为ID. 这个SECONDARY表有一个组合键ID和一个表示语言环境的 varchar。

So, in the Primaryentity I want to have a field of type Map<String, Secondary>where the key is the locale string from the SECONDARYtable and the entry is the Secondaryentity. My Secondaryclass looks like this:

因此,在Primary实体中,我想要一个类型的字段,Map<String, Secondary>其中键是SECONDARY表中的区域设置字符串,条目是Secondary实体。我的Secondary课是这样的:

@Entity
public class Secondary
{
     @Id
     private Long id;
     @Id
     private String locale;
     private String str1;
     private String str2;
     .....
}

I'm thinking I want to use the @MapKeyJoinColumnannotation, but I can't seem to get the other annotations to work. I tried this:

我想我想使用@MapKeyJoinColumn注释,但我似乎无法让其他注释起作用。我试过这个:

@OneToMany
@JoinColumn(name="ID")
@MapKeyJoinColumn(name="LOCALE")
private Map<String, Secondary> secondaryByLocale;

This resulted in it trying to select a column named secondaryByLocale_key which doesn't exist.

这导致它尝试选择一个不存在的名为 secondaryByLocale_key 的列。

I then tried this:

然后我尝试了这个:

@OneToMany
@JoinTable(name="SECONDARY", 
        joinColumns={@JoinColumn(name="ID")},
        inverseJoinColumns=@JoinColumn(name="ID"))
@MapKeyJoinColumn(name="LOCALE")
private Map<String, Secondary> secondaryByLocale;

This results in the following error:

这会导致以下错误:

Exception Description: The @JoinColumns on the annotated element [field secondaryByLocale] from the entity class [class com.foo.Primary] is incomplete. When the source entity class uses a composite primary key, a @JoinColumn must be specified for each join column using the @JoinColumns. Both the name and the referencedColumnName elements must be specified in each such @JoinColumn.

I tried adding the referencedColumnName to the annotation (I wasn't sure what it even should be), but I got the same error.

我尝试将 referencedColumnName 添加到注释中(我什至不确定它应该是什么),但我遇到了同样的错误。

As suggested, I tried using @MapKeyas follows:

按照建议,我尝试使用@MapKey如下:

@OneToMany
@JoinColumn(name="ID")
@MapKey(name="LOCALE")
private Map<String, Secondary> secondaryByLocale;

This results in the following error:

这会导致以下错误:

Exception Description: The map key [LOCALE] on the entity class [class com.foo.Secondary] could not be found for the mapping [org.eclipse.persistence.mappings.UnidirectionalOneToManyMapping[secondaryByLocale]].

Maybe I'm going about this all wrong, and there's a better way to annotate the Map field. Any help would be much appreciated.

也许我对这一切都做错了,并且有一种更好的方法来注释 Map 字段。任何帮助将非常感激。

采纳答案by MattR

Try using @MapKey(name = "locale")instead.

尝试使用@MapKey(name = "locale")

@MapKeyJoinColumnis used when your map key is an entity, but here you're just using the locale String.

@MapKeyJoinColumn当您的地图键是实体时使用,但在这里您只使用区域设置字符串。

回答by Kedar Birajdar

In my case, it is worked with @OneToMany(cascade=CascadeType.PERSIST) @MapKeyColumn(name="COLUMN_NAME")

就我而言,它与 @OneToMany(cascade=CascadeType.PERSIST) @MapKeyColumn(name="COLUMN_NAME") 一起使用

or

或者

You can directly try with only @OneToMany(cascade=CascadeType.PERSIST)

你可以直接尝试只用@OneToMany(cascade=CascadeType.PERSIST)