我很遗憾用JPA注释映射以下结构。
+===========+ +====================+
| Offer | | Text |
+-----------+ 1 0..* +--------------------+
| id (pk) |-------------| textkey (pk) |
| namekey | | languagecode (pk) |
| ... | | text |
+===========+ | ... |
+====================+
因此,每个Offer都有一个知道i18n的名称。因为我在应用程序中反复出现相同的情况(Offer也有i18n注释,文章有i18n名称等)我希望有一个带有复合主键的Text实体。对于每个密钥,存在与支持的语言一样多的记录。文字样本:
+=====================================+
| textkey | languagecode | text |
+=====================================+
| offer5Name | en | foo |
| offer5Name | fr | bar |
| offer6Name | en | hello |
...
Offer实体会将Text#textkey存储在其namekey列中。
在Java方面,我希望提供一组名称,甚至更好的名称映射,这样我就可以使用Text getName(String language)
而不是Set<Text> getNames()
的方法。
我已经拥有的是Text及其复合主键TextPK:
@Entity
public class Text {
@EmbeddedId
private TextPK primaryKey;
@Column(name = "text")
private String text;
PK
@Embeddable
public class TextPK implements Serializable {
@Column(name = "textkey")
private Long key;
@Column(name = "languagecode")
@Enumerated(EnumType.STRING)
private LanguageCode languageCode;
问题:如何在Offer类中注释'names'成员变量以获得我需要的内容?
答案 0 :(得分:2)
好的,我再次回答我自己的问题......
JPA 1.0不支持单向OneToMany(http://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.0_unidirectional_OneToMany_relationship_database),这就是我最终会得到的结果。
对我的案例最有效的方法是创建一个中间TextCollection
实体。每个域实体(例如Offer
)对于其每个文本属性(名称,描述等)都与TextCollection
具有OneToOne关系。集合实体本身只有与Text
的id和双向OneToMany关系。
@Entity
@Table(name = "textcollection")
public class TextCollection {
@Id
@Column(name = "textkey")
private String key;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "textCollection")
private final Set<Text> texts = new HashSet<Text>();
@Entity
@Table(name = "text")
public class Text {
@EmbeddedId
private TextPK primaryKey;
@Column(name = "text", nullable = false)
private String text;
@ManyToOne
@JoinColumn(name = "textkey", insertable = false, updatable = false)
private TextCollection textCollection;
@Entity
@Table(name = "offer")
public class Offer {
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "namekey", nullable = false, insertable = true)
private TextCollection name;