![](/img/trans.png)
[英]Map JPA Embedded entity class id to Embeddable entity class id
[英]JPA map an Embeddable class which contains a Map<Entity, Embeddable>
我正在使用JPA编写Java EE应用程序,并且需要对其进行国际化。 为此,我创建了一个名为MultilingualString
的类,该类将Language
与String
相关联(因此扩展了HashMap<Language, String>
),如下所示:
/**
* This class is mapped to the database thanks
* to the Locale.toLanguageTag() method
* and Locale.fromLanguageTag(String) constructor
*/
public class Language {
public Locale locale;
/* Getters, Setters ... */
}
/**
* NB : This class extends HashMap to override the put method
* which needs to ignore putting null values instead of throwing
* a NullPointerException
*/
public class MultilingualString extends HashMap<Language, String> {
public Map<Language, String> getStrings() {
return (this);
}
/* ... */
}
现在,假设我们有一个Entity
,该Entity
名称取决于Language
:
@Entity
@Access(AccessType.PROPERTY)
public class Entity {
private Long id;
private MultilingualString name;
@Id
public Long getId() { ... }
@Transient
public MultilingualString getName() { ... }
@ElementCollection
@MapKeyJoinColumn(name = "language_id")
public Map<Language, String> getStrings() {
return (this.name.getStrings());
}
/* ... */
}
此代码产生以下数据库架构:
Language :
id | bigint | NOT NULL | primary key
languageTag | character varying(255) | |
---------------------------------------------------------------------------------------------------
Entity :
id | bigint | NOT NULL | primary key
---------------------------------------------------------------------------------------------------
Entity_strings :
entity_id | bigint | | foreign key references Entity(id)
language_id | bigint | | foreign key references Language(id)
string | character varying(255) | |
哪个好
此实现的问题是,在MultilingualString
字段上重复@Transient
,在getStrings()
方法上重复@ElementCollection @MapKeyJoinColumn
getStrings()
每次需要在数据库BTW中映射MultilingualString
,都必须重新编写:至少1个/实体类)。 在我看来,它使代码难看且难以维护。
另一件事是:是通过Map
将Language
与String
关联的Entity
。 应该有一个将它们都关联起来的类:如我在这里所读,说一个LocalizedString
所以我希望MultilingualString
表现得像一个值类型,所以我不需要重复上面提到的多个注释并实现LocalizedString
。
以下是我到目前为止提出的内容。 它不起作用,GlassFish不会以这样的映射开始,当EclipseLink看到MultilingualString
映射时,我总是得到java.util.NoSuchElementException
。
@Embeddable
public class LocalizedString {
@ManyToOne
private Language language;
private String string;
}
@Embeddable
public class MultilingualString extends HashMap<Language, LocalizedString> {
/**
* Here I lost myself in all the available annotations
* and tried thousands of permutation, but always the same exception
* @MapKeyJoinColumn ?
* @MapKeyClass ?
* @CollectionTable ?
* ...
*/
@ElementCollection
public Map<Language, LocalizedString> getStrings() {
return (this);
}
}
@Entity
public class Entity {
@Id
private Long id;
@Embedded
private MultilingualString name;
}
因此,我希望通过这种实现,获得与上面相同的(或最可能的)数据库映射。 那有可能吗? 我读到一个Embeddable
类不应包含另一个(的集合) Embeddable
类,但是在这里,对我来说就是这种情况。
我读了几篇文章和博客,但没有发现如此多的情况(“带有实体键和可嵌入值的JPA映射”)
实际上,除了我的地图值是Embeddable
类之外,我正在尝试执行与此类似的操作。 我在StackOverflow上发现了一种类似的情况 (只是我希望他的Root
类是Embeddable
),我测试了一个答案(没有运气),但是没有“被标记为答案”,并且这个问题没有太多成功。
这是可以处理您实体的本地化的方面的示例:
@Aspect
public class LocalizationAspect {
@AfterReturning(
pointcut = "@within(MyManager) && execution(MyEntity methodThatReturnsEntity(..))",
returning = "entity"
)
public void localizeMyEntity(MyEntity entity) {
localize(entity);
}
}
稍作更改,您就可以将其应用于返回的实体的集合...
localie()使用实体ID在返回结果之前导航本地化信息并将其注入该实体。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.