考虑我想在JPA中表示的以下遗留数据模型:
id
和name
。id
和language_id
组成的复合主键,另外还有一个description
,因此每个翻译都有一个条目用于每种语言。languagedescription_id
确定。现在,我的第一种方法是对像
这样的实体进行建模@Entity
public class Language {
@Id
@Column(length = 3)
private String id;
private String languageDescription;
// ...
}
@Embeddable
public class LanguageDescriptionId implements Serializable {
@Column(length = 9)
private String id;
@Column(length = 3)
private String languageId;
// ...
}
@Entity
public class LanguageDescription {
@EmbeddedId
private LanguageDescriptionId languageDescriptionId;
@ManyToOne
@MapsId(value = "languageId")
private Language language;
@Column(length = 60)
private String description;
// ...
}
@Entity
public class Article {
@Id
private String id;
@ManyToOne
private LanguageDescription languageDescription;
}
其中a)不正确,因为技术上文章可以有一个翻译列表(理想情况下是语言到语言描述的映射,以便轻松获取给定语言的翻译)和b)导致数据库情况,即我的ORM(EclipseLink)将languagedescription
的主键列添加到article
表,尽管文章仅引用languagedescription_id
以防止多个冗余条目。用
Article
实体时
@Entity
public class Article {
@Id
private String id;
@ManyToMany
private List<LanguageDescription> languageDescriptions;
}
我的ORM创建了一个映射表,我必须手动填充该映射表,并使用冗余信息扩展(遗留)数据模型。目前我的方法是为Article
实体建模,如
@Entity
public class Article {
@Id
private String id;
@Column(length = 9)
private String languageDescriptionId;
}
同时省略JPA支持并在@EntityListener
中获取翻译。
现在,这种情况在JPA中是否可以自动管理,或者这些“隐含”的多对多关系没有JPA根本不支持的映射表?
public class Main {
public static void main(String[] args) {
final Language english = createLanguage("language_1", "English");
final Language german = createLanguage("language_2", "German");
createArticle1(english, german);
createArticle2(english, german);
}
private static Language createLanguage(String id, String languageDescription) {
final Language language = new Language();
language.setId(id);
language.setLanguageDescription(languageDescription);
return language;
}
private static void createArticle1(Language english, Language german) {
final String languageDescriptionId = "languagedescription_1";
final LanguageDescription languageDescription1 = new LanguageDescription();
final LanguageDescriptionId languageDescriptionId1 = new LanguageDescriptionId();
languageDescriptionId1.setId(languageDescriptionId);
languageDescriptionId1.setLanguageId(english.getId());
languageDescription1.setLanguageDescriptionId(languageDescriptionId1);
languageDescription1.setLanguage(english);
languageDescription1.setDescription("Engine");
final LanguageDescription languageDescription2 = new LanguageDescription();
final LanguageDescriptionId languageDescriptionId2 = new LanguageDescriptionId();
languageDescriptionId2.setId(languageDescriptionId);
languageDescriptionId2.setLanguageId(german.getId());
languageDescription2.setLanguageDescriptionId(languageDescriptionId2);
languageDescription2.setLanguage(german);
languageDescription2.setDescription("Motor");
final Article article1 = new Article();
article1.setId("a_1");
article1.setLanguageDescriptionId(languageDescriptionId);
}
private static void createArticle2(Language english, Language german) {
final String languageDescriptionId = "languagedescription_2";
final LanguageDescription languageDescription3 = new LanguageDescription();
final LanguageDescriptionId languageDescriptionId3 = new LanguageDescriptionId();
languageDescriptionId3.setId(languageDescriptionId);
languageDescriptionId3.setLanguageId(english.getId());
languageDescription3.setLanguageDescriptionId(languageDescriptionId3);
languageDescription3.setLanguage(english);
languageDescription3.setDescription("Turn Signal");
final LanguageDescription languageDescription4 = new LanguageDescription();
final LanguageDescriptionId languageDescriptionId4 = new LanguageDescriptionId();
languageDescriptionId4.setId(languageDescriptionId);
languageDescriptionId4.setLanguageId(german.getId());
languageDescription4.setLanguageDescriptionId(languageDescriptionId4);
languageDescription4.setLanguage(german);
languageDescription4.setDescription("Blinker");
final Article article2 = new Article();
article2.setId("a_2");
article2.setLanguageDescriptionId(languageDescriptionId);
}
}
答案 0 :(得分:0)
以下内容是可能的:
@Entity
public class Article {
@Id
private String id;
@Column(length = 9)
private String languageDescriptionId;
@OneToMany
@JoinColumn(name="ID", referencedColumnName="LANGUAGEDESCRIPTIONID", insertable=false, updatable=false)
private List<LanguageDescription> languageDescriptions;
}
现在上面的OneToMany不符合JPA,因为LanguageDescription有一个复合PK,所以EclipseLink和其他提供程序会抛出验证异常,它只是它的外观的一个例子。您将需要使其成为临时的或添加另一个连接列,只是为了绕过验证,然后在描述符定制器中修改或添加映射。这在jpa, eclips-link 2.5.1: OneToMany not working on columns not primary key
的答案中有所描述和显示