web-dev-qa-db-ja.com

JPAでreferenceColumnNameは何に使用されますか?

JPAにはreferencedColumnNameと呼ばれる属性があり、@JoinColumn, @PrimaryKeyJoinColumnに設定できます。この設定の背後にある考え方は、誰かがこれを使用できる場所の良い例を挙げることができますか?

61
ams

別の列をデフォルトとして指定するためにありますid他のテーブルの列、例えば以下を考慮してください

TableA
  id int identity
  tableb_key varchar


TableB
  id int identity
  key varchar unique

// in class for TableA
@JoinColumn(name="tableb_key", referencedColumnName="key")
60
Firo

「referencedColumnName」プロパティは、注釈を付けている列を参照しているテーブル内の列の名前です。または簡単に言うと、宛先テーブルで参照される列です。このようなものを想像してください:車と人。 1人の人が多くの車を所有できますが、1台の車は1人の人しか所有していません(申し訳ありませんが、私の車を運転している人はいません)。

テーブルパーソン
name char(64)主キー
age int

テーブルカー
car_registration char(32)主キー
car_brand(char 64)
car_model(char64)
owner_name char(64)外部キー参照 人(名前)

クラスを実装すると、次のようになります

class Person{
   ...
}

class Car{
    ...
    @ManyToOne
    @JoinColumn(columnName="owner_name", referencedColumnName="name")
    private Person owner;
}

お役に立てれば。

38
EAmez

引用 referencedColumnNameのAPI

この外部キー列によって参照される列の名前。

デフォルト(単一結合列が使用されている場合のみ適用):参照されるテーブルの主キー列と同じ名前。

Q/A

これはどこで使用されますか?

参照されるテーブルに複合PKがある場合、参照する列名を指定する必要があります。

20
JMelnik
  • name属性は、関連付けを含む列、つまり外部キーの列名を指します
  • referencedColumnName属性は、関連付けられた/参照されたエンティティの関連列、つまり主キーの列名を指します

参照されるエンティティにPKとして単一の列がある場合、referencedColumnNameを入力する必要はありません。それは、参照する列(つまり、Addressの単一列ID)に疑いがないからです。

@ManyToOne
@JoinColumn(name="ADDR_ID")
public Address getAddress() { return address; }

ただし、参照されるエンティティに複数の列にまたがるPKがある場合、@JoinColumn注釈を指定する順序には重要性があります。 referencedColumnNameを指定しなくても動作する場合がありますが、それは幸運です。したがって、次のようにマッピングする必要があります。

@ManyToOne
@JoinColumns({
    @JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
    @JoinColumn(name="ADDR_Zip", referencedColumnName="Zip")
})
public Address getAddress() { return address; }

またはManyToManyの場合:

@ManyToMany
@JoinTable(
    name="CUST_ADDR",
    joinColumns=
        @JoinColumn(name="CUST_ID"),
    inverseJoinColumns={
        @JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
        @JoinColumn(name="ADDR_Zip", referencedColumnName="Zip")
    }
)

実生活の例

同じ結合テーブルマッピングのHibernateによって生成された2つのクエリ。両方とも参照列が指定されていません。 @JoinColumn注釈の順序のみが変更されました。

/* load collection Client.emails */ 
select 
emails0_.id_client as id1_18_1_,
emails0_.rev as rev18_1_,
emails0_.id_email as id3_1_,
email1_.id_email as id1_6_0_

from client_email emails0_ 
inner join email email1_ on emails0_.id_email=email1_.id_email 

where emails0_.id_client='2' and 
emails0_.rev='18'
/* load collection Client.emails */ 
select
emails0_.rev as rev18_1_,
emails0_.id_client as id2_18_1_,
emails0_.id_email as id3_1_, 
email1_.id_email as id1_6_0_

from client_email emails0_ 
inner join email email1_ on emails0_.id_email=email1_.id_email 

where emails0_.rev='2' and 
emails0_.id_client='18'

クライアントの電子メールを取得するために、結合テーブルを照会しています。 {2, 18}は、クライアントの複合IDです。列名の順序は、@JoinColumn注釈の順序によって決まります。両方の整数の順序は常に同じであり、おそらく休止状態でソートされているため、結合テーブル列との適切なアライメントが必要であり、マッピング順序に依存できない、または依存する必要があります

興味深いのは、整数の順序がエンティティにマッピングされる順序と一致しないことです。その場合、{18, 2}が期待されます。そのため、Hibernateはクエリで使用する前に列名をソートしているようです。これが当てはまり、referencedColumnNameを必要としないのと同じ方法で@JoinColumnを注文する場合、これは説明のためだけに言っています。

適切に入力されたreferencedColumnName属性は、あいまいさのないまったく同じクエリ、私の場合は2番目のクエリ(rev = 2id_client = 18)になります。

2つのテーブルの一般的な場合のJPA 2.xの使用例では、@OneToMany単方向結合 https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.x_unidirectional_OneToMany_relationship_annotations を参照

このWikiBooks JPA記事のスクリーンショット: JPA 2.x単方向OneToMany関係データベースの例

0
Progster219

(オプション)この外部キー列によって参照される列の名前。

  • ここで説明するケース以外のエンティティリレーションシップマッピングで使用する場合、参照される列はターゲットエンティティのテーブルにあります。
  • 単方向のOneToMany外部キーマッピングで使用する場合、参照される列はソースエンティティのテーブルにあります。
  • JoinTableアノテーション内で使用される場合、参照されるキー列は所有エンティティのエンティティテーブルにあります。結合が逆結合定義の一部である場合は、逆エンティティにあります。
  • CollectionTableマッピングで使用される場合、参照される列はコレクションを含むエンティティのテーブルにあります。

例:

Dept
   Long id;
   String deptNo;
   String name;

Employee
  Long id;
  String EmpNo;
  String Name;
  @JoinColumn(name = "dept", referencedColumnName = "deptNo")
  Dept dept;
0