0

テーブル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;

ただし、実行すると、idではなく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 as Translat4_13_1_、translatab0_.id as id1_、translatab0_.lang as Lang1_、translatab0_.id as id22_0_、translatab0_.lang as Lang22_0_、translatab0_.text as Text22_0_ as tblTranslateableText translatab0_ where translatab0_.text as Text22_0_ from tblTranslateableText translatab0_ where 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のIDを手動で管理する必要があるため、あまり便利ではありません(そのため、Hibernateはマッピングされていない列について文句を言いますTranslatableDescriptionId)。

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

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

したがって、 (あなたが言うように、カテゴリ、アイテム、フォルダ)translatableDescriptionIdのすべての「ターゲット」に一意のを手動で割り当て、永続化する前にこの値を手動で設定する必要があります(単に追加することはできません)。TranslatableTextidTranslatableTextTranslatableTextSet

-

ただし、より便利な設計は、特定のターゲットに関連付けられたすべてのトランザクションのIDを維持するために中間エンティティを導入することです。

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 に答える