JPA - @OneToMany作为Map

25

这似乎是一个很常见的情况,但是作为JPA新手,我很难搞清楚。我正在使用EclipseLink和PostgreSQL,但这应该只涉及到JPA规范。

我有一个名为PRIMARY的表,它有一个ID和一堆其他列。还有另一个名为SECONDARY的表,它有一个外键指向PRIMARY表,也叫做ID。这个SECONDARY表有一个由那个ID和表示语言环境的varchar组成的复合主键。

因此,在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;
     .....
}

我在考虑使用@MapKeyJoinColumn注解,但是似乎无法使其他注解工作。我尝试了以下代码:

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

结果导致它尝试选择一个名为secondaryByLocale_key的列,但该列不存在。

然后我尝试了这个:

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

这会导致以下错误:

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.

我尝试在注解中添加referencedColumnName(甚至不确定应该是什么),但是我还是得到了相同的错误。

如建议所示,我尝试使用@MapKey,代码如下:

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

这会导致以下错误:

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]].

也许我一直以来都做错了,可能有更好的方法对 Map 字段进行注释。任何帮助都将不胜感激。

2个回答

23
尝试使用@MapKey(name = "locale")替代。 @MapKeyJoinColumn用于当您的映射键是实体时使用,但在这里您只是使用了字符串locale。

1
如果那不起作用,你能发布你的“Secondary”类的代码吗? - MattR
我已经更新了问题,包括“Secondary”代码和尝试使用“@MapKey”的结果。 - dnc253
我已经更新了我的回答 - 你的实体属性叫做"locale"而不是"LOCALE"。 - MattR
1
另外,你确定在你的Secondary实体上有两个@Id字段是有效的吗? - MattR
有趣的是,我以前没有遇到过大小写敏感的问题,但这绝对解决了它。此外,两个 @Id 注释似乎也很好用。非常感谢你的帮助! - dnc253
1
太好了 :-) 有大小写敏感性,当您引用表列名称时,结果会混合,但在这里,您正在引用类属性(用作Map键),因此绝对区分大小写。 - MattR

1
在我的情况下,它与@OneToMany(cascade=CascadeType.PERSIST)和@MapKeyColumn(name="COLUMN_NAME")一起使用。
或者,您可以直接尝试只使用@OneToMany(cascade=CascadeType.PERSIST)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接