2010-08-14 57 views
0

我很遗憾将以下结构映射到JPA注释。与JPA @OneToMany和复合PK丢失

+===========+    +====================+ 
| Offer  |    | Text    | 
+-----------+ 1  0..* +--------------------+ 
| id (pk) |-------------| textkey (pk)  | 
| namekey |    | languagecode (pk) | 
| ...  |    | text    | 
+===========+    | ...    | 
          +====================+ 

因此,每个要约的名称都是国际知名的。由于我在应用程序中反复使用了相同的案例(提供的内容还包括i18n评论,Article有国际化名称等)。我想要一个带有复合主键的Text实体。对于每个关键字,都有与支持语言一样多的记录。文本示例:

+=====================================+ 
| textkey | languagecode | text | 
+=====================================+ 
| offer5Name | en   | foo  | 
| offer5Name | fr   | bar  | 
| offer6Name | en   | hello | 
... 

要约实体会将Text#textkey存储在其namekey列中。

在Java方面,我希望Offer有一组名称或更好的名称映射,所以我可以使用类似Text getName(String language)而不是Set<Text> getNames()的方法。

我已经是文本及其复合主键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; 

问:我怎么注释的要约类的“名”的成员变量来获得我需要的?

回答

2

好了,再次声明,我回答我的问题...

JPA 1.0不支持单向一对多(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;