我有一个表Category和一个表TranslatableText。类别是这样的

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;


但是在执行时,它尝试访问TranslatableDescriptionId,而不是id。即使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;


选择了错误名称的查询:

从tblTranslateableText inlatab0_(' 119”,“ 103”,“ 116”,“ 121”,“ 107”,“ 113”,“ 101”,“ 109”,“ 105”,“ 123”,“ 106”,“ 125”,“ 124” ,'114')

如果我将映射@JoinColumn更改为read

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


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

org.hibernate.MappingException:无法在org.hibernate.mapping.Table(Category)及其相关的超表和辅助表中找到逻辑名称为id的列

为了很好的措施,我还尝试了:

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


那给了我错误:

org.hibernate.MappingException:无法在org.hibernate.mapping.Table(Category)及其相关的超表和辅助表中找到逻辑名称为TranslatableDescriptionId的列

有什么建议我应该做什么?我真的希望Category的translationableText包含其描述的所有译文,所以我真的很想加入Category.TranslatableDescriptionId == TranslatableText.id

UPDATE1:
TranslatableText被许多实体使用,因此不能在其中放入categoryId并反转关系。

UPDATE2:
我能够用@JoinColumn(name="id")加载它,但是这导致了Hibernate中的ClassCastException,在这里,它没有将Integer作为键,而是将一个包含单个Integer作为键的数组。不能将其转换为字符串,从而无法转换为正确的SQL。所以可能仍然不是我想要的映射

干杯

尼克

最佳答案

这种映射是可能的,但不是很方便,因为您必须手动管理TranslatableText的身份(这就是Hibernate抱怨未映射列TranslatableDescriptionId的原因):

public class Category implements Serializable {
    ...
    private Long translatableDescriptionId;

    @OneToMany
    @JoinColumn(name="id", referencedColumnName="TranslatableDescriptionId")
    private Set<TranslatableText> translatableText;
    ...
}


因此,您需要为translatableDescriptionId的所有“目标”(如您所说的类别,项目,文件夹)手动分配唯一的TranslatableText,并在持久化之前手动将此值设置为idTranslatableText。不只是将TranslatableText添加到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));

07-24 16:33