代码之家  ›  专栏  ›  技术社区  ›  Marcel Stör

与jpa@onetomany和composite pk一起丢失

  •  0
  • Marcel Stör  · 技术社区  · 15 年前

    我对用JPA注释映射下面的结构非常迷茫。

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

    所以,每个报价都有一个我知道的名字。由于我在应用程序中反复出现相同的情况(offer也有一个i18n注释,文章有一个i18n名称等),所以我希望有一个具有复合主键的文本实体。对于每个键,记录的数量与支持的语言的数量一样多。文本样本:

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

    offer实体将在其namekey列中存储text textkey。

    在Java方面,我希望提供一组名称或甚至更好的名字地图,这样我就可以有一个方法。 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;
    

    问题:如何在offer类中注释“name”成员变量以获得所需的内容?

    1 回复  |  直到 15 年前
        1
  •  2
  •   Marcel Stör    15 年前

    好吧,我又在回答我自己的问题…

    JPA 1.0不支持单向OneTomany( http://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.0_unidirectional_OneToMany_relationship_database )这就是我最终的结局。

    对我来说最有效的办法是建立一个中间人 TextCollection 实体。每个域实体(如 Offer )与一对一的关系 文本集 对于每个文本属性(名称、描述等)。集合实体本身除了与 Text .

    @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;