Hibernate: соединение с одним из ключей многоключевой таблицы - PullRequest
0 голосов
/ 17 сентября 2010

У меня есть таблица 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));

В моей сущности Category я определил отображение:

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

Но когда он выполняется, он пытается получить доступ к TranshableDescriptionId, а не к 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;

Запрос с выбранным неверным именем:

выберите значение transatab0_.TranshableDescriptionId в качестве Translat4_13_1_, transatab0_.id в качестве id1_, transatab0_.lang в качестве Lang1_, translationatab0_.id как id22_0_, transatab0_.lang как Lang22_0_, transatab0_.text как Text22_0_ из tblTranslateableText translationatab0_, где transatab0_.TranslatableDescriptionId в ('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) и связанных с ним супертаблиц и вторичных таблиц

Для хорошей меры я также попытался:

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

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

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

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

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

ОБНОВЛЕНИЕ2: я смог загрузить его, сказав @JoinColumn(name="id"), но это привело к ClassCastException в Hibernate, где он, вместо того, чтобы иметь Integer в качестве ключа, имеетМассив, содержащий одно целое число в качестве ключа.Это не может быть преобразовано в строку и, следовательно, в правильный SQL.Так что это, вероятно, все еще не отображение, которое я хочу

Приветствия

Nik

1 Ответ

2 голосов
/ 17 сентября 2010

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

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

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

Таким образом, вам нужно вручную назначить уникальные translatableDescriptionId s для всех "целей" TranslatableText (как вы говорите, категорий, элементов, папок) и вручную установить эти значения как id из TranslatableText, прежде чем сохранять ихВы не можете просто добавить 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)); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...