2010-09-17 29 views
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)); 

我的類別實體我已經定義的映射:

@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 as Lang22_0_,translatab0_.text as 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更改爲re

org.hibernate.MappingException:廣告

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

我裝我的應用程序時,遇到下列錯誤無法找到邏輯名稱列:ID在org.hibernate.mapping.Table(類別)和其相關supertables和輔助表

良好的措施我也試過:

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

這給我的錯誤:

org.hibernate.MappingException:無法找到邏輯名稱列:TranslatableDescriptionId在org.hibernate.mapping.Table(類別)及其相關supertables和輔助表

到我應該做的有什麼建議?我真想類別的translateableText遏制其描述所有的翻譯,所以我真的想加入Category.TranslatableDescriptionId == TranslatableText.id

UPDATE1: TranslatableText是由許多實體使用,所以投入的categoryId在它和扭轉關係不是一種選擇。

UPDATE2: 我能夠加載它說@JoinColumn(name="id"),但是這導致一個ClassCastException在休眠那裏,而不是具有整數作爲關鍵字,具有包含單個整數作爲密鑰數組。這不能被做成一個字符串,因此是適當的SQL。因此,它可能仍然不是映射我想

乾杯

回答

2

這種映射是可能的,但不是很方便,因爲你必須管理的手動TranslatableText身份(這就是爲什麼休眠抱怨非映射列TranslatableDescriptionId):

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

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

所以,你需要手動分配唯一translatableDescriptionId s到的TranslatableText(類別中的所有「目標」 ,項目,文件夾,如你所說)並手動設置這個值爲idTranslatableText然後再堅持它(你不能只是將TranslatableText添加到Set)。

-

然而,更方便的設計是引入一箇中間實體保持attatched到特定目標的所有transalations的身份:

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)); 
+0

謝謝對於這個建議,我馬上嘗試一下這個設計並回報:-)然而,我有點困惑,因爲我閱讀它的方式只是把問題推到了我面前一步? – niklassaers 2010-09-17 11:34:46

+0

'name =「targetId」'分類指向Category.targetId,對不對?或者應該是'name =「id」',因爲它指向TranslationTargets.id,就像TranslationTarget的'name =「targetId」'指向TranslatableText.targetId? – niklassaers 2010-09-17 11:45:07

+0

當這樣做時,我得到以下例外。在我錯過的映射中有什麼嗎? com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:'字段列表'中的未知列'texts0_.targetId' – niklassaers 2010-09-17 12:03:55