web-dev-qa-db-ja.com

Hibernate-エンティティではなく外部キー

現在、Hibernateでは、*-to-one関係で定義されたオブジェクトを直接読み込むことができます。

entity1.getEntity2()

オブジェクトの代わりに外部キーを取得することは可能ですか?

私が見る現在のアプローチは、私のマッピングにaddintを持つことです:

@JoinColumn(name="message_key")
@ManyToOne(targetEntity=Message.class,fetch=FetchType.LAZY)
private Message message;  //these lines currently exist

@Column(name="message_key")
private Long message_fk; //the idea is to add those 2 lines

外部キーを取得するためのより良いアプローチがありますか、これが唯一のものですか?

45
iliaden

はい、できます。休止状態については、次のように、どのマッピングが維持することになっているのかを明確にする必要があります。

@Column(name="message_key", updatable=false, insertable=false)
private Long message_fk;
44
Affe

エンティティへの参照が必要であるが、外部キーを取得するためだけにデータベースからそれをロードしたくない場合、あなたのアプローチは正しいものです。 insert属性とupdatabale = falseをColumn属性に追加して、エンティティへの正しい参照が失われないようにします。

@JoinColumn(name = "message_key")
@ManyToOne(targetEntity = Messages.class, fetch = FetchType.LAZY)
private Messages message;

@Column(name = "message_key", insertable = false, updatable = false)
private Long message_fk;
15
Marcelo

実際、FetchTypeがLAZYの場合、メッセージオブジェクトの代わりに外部キーのみをロードするのがデフォルトのHibernateの動作です。これが、LAZY FetchTypeを指定したときにロードされるオブジェクトへのプロキシがある理由です。

外部キーは直接表示されませんが、もちろんOneToMany関係の「一方」の端にあるオブジェクトのキーです。

ただし、フィールドベースのアクセスタイプ(たとえば、フィールドに注釈が配置される場合)では、未解決の休止状態の問題があります。Hibernateはデータベースからプロキシの背後にあるオブジェクト全体をロードします。 ( http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/

私の具体的な提案は次のとおりです(たとえば、私の場合、「正しい」答えは機能しませんでした)。

  • Hibernateは非外部キーデータが必要な場合にのみメッセージオブジェクトをロードするため、メッセージオブジェクトを直接使用します。外部キーの追加フィールドを指定しないでください。
  • プロパティアクセスを使用するようにクラスを切り替えます。つまり、ゲッターとセッターを定義し、フィールドからゲッターに注釈を入れます。
4
RobertG
Long fk = entity1.getEntity2().getId();

これは動作するはずです。複合主キーが外部キーとして参照されている場合のみ機能しますが、その場合もソリューションは機能しません。私のソリューションを考えると、複合キーでさえそれほど見苦しくありません。

Long fkField1 = entity1.getEntity2().getCol1();
String fkField2 = entity1.getEntity2().getCol2();

そのような何かが動作します。

編集:提案されたソリューションについてさらに考えると、Hibernateはすでにマップされた関係のFKフィールドを自動的に作成しようとしているため、別の@Columnを定義すると2番目の同じ名前の列。

1
Jesse Webb