0

我有一个表类别和一个表 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));

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

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

选择了错误名称的查询:

选择 translatab0_.TranslatableDescriptionId 作为 Translat4_13_1_,translatab0_.id 作为 id1_,translatab0_.lang 作为 Lang1_,translatab0_.id 作为 id22_0_,translatab0_.lang 作为 Lang22_0_,translatab0_.text 作为 Text22_0_ from tblTranslateableText translatab0_ where translatab0_.TranslatableDescriptionId in ('126' 119'、'103'、'116'、'121'、'107'、'113'、'101'、'109'、'105'、'123'、'106'、'125'、'124' , '114')

如果我将映射@JoinColumn 更改为读取

@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 的 translateableText 包含其描述的所有翻译,所以我真的很想加入 Category.TranslatableDescriptionId==TranslatableText.id

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

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

干杯

尼克

4

1 回答 1

2

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

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

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

因此,您需要手动将唯一的 s 分配给(如您所说的类别、项目、文件夹)translatableDescriptionId的所有“目标”,并在持久化之前手动设置此值(您不能只添加到 中)。TranslatableTextidTranslatableTextTranslatableTextSet

--

然而,更方便的设计是引入一个中间实体来保持所有附加到特定目标的转换的身份:

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)); 
于 2010-09-17T09:55:18.740 回答