85

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

4

5 に答える 5

81

別のテーブルのデフォルトの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")
于 2012-06-28T14:09:13.413 に答える
52

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

テーブル個人
名char(64)主キー
年齢int

テーブル
Carcar_registrationchar(32)主キー
car_brand(char 64)
car_model(char64)
owner_name char(64)外部キー参照Person(name)

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

class Person{
   ...
}

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

編集: @ searchengine27がコメントしてcolumnNameいるように、Java7ドキュメントの永続性セクションのフィールドとして存在しません。このプロパティをどこから取得したかは思い出せませんが、使用したことは覚えています。そのため、このプロパティを例に残しています。

于 2012-07-04T11:58:06.077 に答える
24

referenceColumnNameでのAPIの引用:

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

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

Q / A

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

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

于 2012-06-28T13:32:42.767 に答える
12
  • 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 はクエリで使用する前に列名をソートしているようです。これが真実@JoinColumnで、同じ方法で注文する場合は必要ありませんがreferencedColumnName、これは説明のためだけに言います.

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

于 2015-09-22T12:02:12.867 に答える