代码之家  ›  专栏  ›  技术社区  ›  niklassaers

休眠:与多键表的一个键连接

  •  0
  • niklassaers  · 技术社区  · 14 年前

    create table Category (
      id int not null,
      parent_id int default 0,
      TranslatableDescriptionId int default 1,
      primary key(id));
    
    create table TranslatableText (
      id int not null,
      lang enum ('NO','EN','FR'),
      text mediumtext,
      primary key(id, lang));
    

    在我的类别实体中,我定义了一个映射:

    @Fetch(FetchMode.SUBSELECT)
    @Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
    @OneToMany(fetch=FetchType.LAZY)
    @JoinColumn(name="TranslatableDescriptionId")
    @ForeignKey(name="FK_TranslatableTextId")
    private Set<TranslatableText> translatableText;
    

    @Id
    @Column(name = "id", nullable = false)
    private Integer id;
    
    @Id
    @Column(name = "lang", nullable = false)
    @Enumerated(EnumType.STRING)
    private String lang;
    
    @Column(name = "text", length = 400, nullable = false)
    private String text;
    

    选择了名称不正确的查询:

    @JoinColumn(name="TranslatableDescriptionId", referencedColumnName="id")
    

    加载应用程序时出现以下错误:

    @JoinColumn(name="id", referencedColumnName="TranslatableDescriptionId")
    

    这给了我一个错误:

    org.hibernate.MappingException异常:在中找不到逻辑名称为translateableDescriptionId的列org.hibernate.mapping.表(类别)及其相关的超表和次表

    更新1: 可翻译文本被许多实体使用,因此在其中放入categoryId并反转关系不是一种选择。

    @JoinColumn(name="id") ,但这导致了Hibernate中的ClassCastException,它没有将整数作为键,而是将包含单个整数的数组作为键。这无法生成一个字符串,因此无法生成正确的SQL。所以它可能仍然不是我想要的映射

    干杯

    尼克

    1 回复  |  直到 14 年前
        1
  •  2
  •   axtavt    14 年前

    这种映射是可能的,但不是很方便,因为您必须管理 TranslatableText TranslatableDescriptionId ):

    public class Category implements Serializable {
        ...
        private Long translatableDescriptionId;
    
        @OneToMany
        @JoinColumn(name="id", referencedColumnName="TranslatableDescriptionId") 
        private Set<TranslatableText> translatableText;
        ...
    }
    

    所以,您需要手动分配unique translatableDescriptionId 可译文本 id 属于 在坚持之前(你不能只添加 进入 Set

    --

    public class Category {
        ...
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "targetId")
        private TranslationTarget target;
    }
    
    public class TranslationTarget {
        @Id @GeneratedValue
        private Long id;
    
        @OneToMany
        @JoinColumn(name = "targetId")
        private Set<TranslatableText> texts;
    }
    

    -

    create table Category (              
      targetId int,
      ...);        
    
    create table TranslationTargets (
      id int primary key
    );      
    
    create table TranslatableText (              
      targetId int not null,              
      lang enum ('NO','EN','FR'),              
      text mediumtext,              
      primary key(targetId, lang));