アプリケーションの起動時に、 Hibernate ( v 4.2.3 ) に 4 つの既存の DB テーブルを検証 ( = 検証) させようとしています。hbm2ddl.auto
これが私のテーブル作成SQLスクリプトです(これはH2 DBです):
-- Lookup/reference table, example records might be for ADVERB, NOUN,
-- VERB, etc.
CREATE TABLE word_types (
word_type_id BIGINT AUTO_INCREMENT,
word_type_label VARCHAR(100) NOT NULL,
word_type_description VARCHAR(100) NOT NULL,
word_type_tag VARCHAR(100) NOT NULL,
CONSTRAINT uc_tag UNIQUE (word_type_tag)
);
-- A word in the English language. length is the number of chars in the
-- word, type ID is the word_types#word_type_id above (foreign key),
-- text is the actual word itself "quick", "fast", etc.
CREATE TABLE words (
word_id BIGINT AUTO_INCREMENT,
word_length INTEGER NOT NULL,
word_type_id INTEGER NOT NULL,
word_text VARCHAR(100) NOT NULL,
word_definition VARCHAR(1000) NOT NULL,
CONSTRAINT fk_word_types FOREIGN KEY (word_type_id) REFERENCES word_types(word_type_id),
CONSTRAINT uc_text_type UNIQUE (word_text, word_type_id)
);
-- Crosswalk/junction table holding a many-to-many relationships between
-- pairs of words. Example: fast is a synonym of quick. So there would be
-- a words record for fast, and a words record for quick, and a record in
-- this table linking the 2 together.
CREATE TABLE synonyms (
synonym_id BIGINT AUTO_INCREMENT,
base_word_id INTEGER NOT NULL,
has_synonym_id INTEGER NOT NULL,
CONSTRAINT fk_word_1_base_id FOREIGN KEY (base_word_id) REFERENCES words(word_id),
CONSTRAINT fk_word_synonym_id FOREIGN KEY (has_synonym_id) REFERENCES words(word_id),
CONSTRAINT uc_syn_id_sets UNIQUE (base_word_id, has_synonym_id)
);
-- Same as above except this table relates words that are antonyms of
-- each other.
CREATE TABLE antonyms (
antonym_id BIGINT AUTO_INCREMENT,
base_word_id INTEGER NOT NULL,
has_antonym_id INTEGER NOT NULL,
CONSTRAINT fk_word_2_base_id FOREIGN KEY (base_word_id) REFERENCES words(word_id),
CONSTRAINT fk_word_antonym_id FOREIGN KEY (has_antonym_id) REFERENCES words(word_id),
CONSTRAINT uc_ant_id_sets UNIQUE (base_word_id, has_antonym_id)
);
したがって、4 つのテーブル: words
、synonyms
& antonyms
(さまざまな 間の多対多の関係を保持するwords
) とルックアップ/参照テーブルword_types
(ADVERB、NOUN など)。明確にするために、 "quick"words
の値を持つレコードと"fast" のword_text
別のwords
/レコード/値がある場合、 "quick" の ID でword_text
あるエントリがsynonyms
テーブルに存在する可能性があり、"高速のID; quickにはfastという同義語があるためです。これらのテーブルに使用したいJavaモデルは次のとおりです。base_word_id
has_synonym_id
public class BaseModel {
protected Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
public class Word extends BaseModel {
private String text;
private Integer length;
private WordType type;
private String definition;
private List<Word> synonyms;
private List<Word> antonyms;
// Getters, setters, ctors omitted for brevity...
}
public class BaseLookup extends BaseModel {
private String label;
private String description;
private String tag;
// Getters, setters, ctors omitted for brevity...
}
public class WordType extends BaseLookup {
public WordType(String label, String description, String tag) {
super(label, description, tag);
}
}
そのBaseModel
ため、各モデルに ID を提供します。BaseLookup
すべてのルックアップ テーブルに少なくとも 3 つのフィールド/列があります。Word
非常に単純明快でWordType
、親にフィールドを追加しないルックアップ ラッパーです。しかし、いつの日か、提供されるラベル/説明/タグ フィールドを超えてフィールドを追加するBaseLookup
サブクラスを持つことが非常に考えられるかもしれませんBaseLookup
。
そのため、Java とデータ モデルの両方を使用するように Hibernate が正しく構成されるように、各クラスに追加する必要がある注釈を見つけようとしていますが、いくつかのレンガの壁にぶつかっています。これが私が思いついた最高のものです:
// This class doesn't translate into a table; it's just a base class that provides
// an ID for all other entities, and perhaps (down the road) other common fields as
// well.
public class BaseModel {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
protected Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name="words")
public class Word extends BaseModel {
// How do I force Word.getId() to be "words_id"?
@Column(name="word_text")
private String text;
@Column(name="word_length")
private Integer length;
// But how do I make this the ID of a word_types record?
@Column(name="word_type_id")
private WordType type;
@Column(name="word_definition")
private String definition;
// The words table doesn't have any synonyms or antonyms.
// Rather there is a many-to-many relationship between
// a word and its synonyms and its antonyms...
@Column(name="???")
private List<Word> synonyms;
@Column(name="???")
private List<Word> antonyms;
// Getters, setters, ctors omitted for brevity...
}
// Not sure what to annotate this table with, because there is not
// base_lookup table or anything like that...
public class BaseLookup extends BaseModel {
private String label;
private String description;
private String tag;
// Getters, setters, ctors omitted for brevity...
}
// Furthermore, here, in the case of WordType, I'd like to force the parent
// fields to be "word_type_label", "word_type_description", and "word_type_tag";
// however, other BaseLookup subclasses should be able to force those same fields
// to map/bind to other tables with other field names.
//
// For example, I might some day want a Color POJO relating to a colors table with
// the following fields: color_label, color_description and color_tag, etc.
public class WordType extends BaseLookup {
// How do I force WordType.getId() to be word_type_id?
public WordType(String label, String description, String tag) {
super(label, description, tag);
}
}
Hibernate が Java とデータ モデルの両方に対応できるように、戦いに疲れた Hibernate のベテランが POJO クラス/フィールドに正しく注釈を付けるのを手伝ってくれますか? 具体的には、次のソリューションが必要です。
- 他のすべてのエンティティの IDを作成する方法ですが、エンティティごとに一意の列名 ( 、color_id` など)
BaseModel#id
を持つ一意の列として表示されます。word_id
word_type_id
Word#type
Hibernate がword_type_id
外部キーであることを認識できるように、フィールドに注釈を付ける方法。Word
また、 DB から POJO インスタンスを取得するときに、そのWordType
タイプが既に取り込まれているようにカスケードする必要があります。- 注釈を付け
Word#synonyms
てWord#antonyms
、Hibernate がそれらの関係を (同じ名前の) crosswalk テーブルに保存する方法。 - Hibernate が次のフィールドで呼び出されるテーブルを探すことを認識するように注釈を付ける方法
WordType
など: 、および。しかし、他のサブクラスも持つことができるような方法でそれらに注釈を付けてください.BaseLookup
word_types
word_type_label
word_type_description
word_type_tag
BaseLookup
Color
colors
color_label
color_description
color_tag
前もって感謝します!