2010-09-17 6 views
0

У меня есть таблица Категория и таблица TranslatableText. Категория как этотHibernate: соединение с одним из ключей таблицы с несколькими ключами

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, а не идентификатор. Даже если 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_ из tblTranslateableText translatab0_, где translatab0_.TranslatableDescriptionId в ('126', '119', '103', '116', '121', '107', '113', ' 101 ',' 109 ',' 105 ',' 123 ',' 106 ',' 125 ',' 124 ',' 114 ')

Если я изменил сопоставления @JoinColumn на re Объявление

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

Я получаю следующее сообщение об ошибке при загрузке моего приложения:

org.hibernate.MappingException: Невозможно найти столбец с логическим именем: Удостоверение личности в org.hibernate.mapping.Table (категория) и его связанные надтаблиц и вторичные таблицы

Для пущей я также пытался:

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

Это дало мне ошибку:

org.hibernate.MappingException: Невозможно найти столбец с логическим именем: TranslatableDescriptionId в org.hibernate.mapping.Table (категория) и связанных с ним надтаблиц и вторичных таблиц

Любые предложения на то, что я должен делать? Я действительно хочу translateableText категории, чтобы содержать все переводы для его описания, так что я действительно хочу, чтобы присоединиться к Category.TranslatableDescriptionId == TranslatableText.id

Update1: TranslatableText используется многими субъектами, поэтому ввод в CategoryId в нем и изменение отношения не является вариантом.

UPDATE2: я был в состоянии загрузить его говоря @JoinColumn(name="id"), но это привело к ClassCastException в спящем режиме, когда он, вместо того, чтобы в Integer в качестве ключа, имеет массив, содержащий один Integer в качестве ключа. Это не может быть превращено в строку и, следовательно, правильный SQL.Так что это, вероятно, до сих пор не отображение Я хочу

Приветствия

Nik

ответ

2

Этот вид отображения можно, но не очень удобно, потому что вам придется управлять тождественность TranslatableText s вручную (поэтому Hibernate жалуется, не отображенные в колонке TranslatableDescriptionId):

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

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

Итак, вам нужно вручную назначить уникальные translatableDescriptionId с для всех «мишеней» TranslatableText (категории , элементы, папки, как вы говорите) и вручную установите эти значения как id из TranslatableText, прежде чем продолжать его (вы не можете просто добавить TranslatableText в Set).

-

Однако более удобный дизайн ввести промежуточный объект, чтобы сохранить идентичность всех transalations attatched к конкретной цели:

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

+0

'name = "targetId"' в категории указывает на Category.targetId, правильно? Или это должно быть «name =« id », потому что оно указывает на TranslationTargets.id, точно так же, как« Name = «targetId» «TranslationTarget» указывает на TranslatableText.targetId? – niklassaers

+0

При этом я получаю следующее исключение. Есть что-то в сопоставлениях, которые я пропустил? com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Неизвестный столбец 'text0_.targetId' в 'списке полей' – niklassaers