JPAには、この設定の背後にある考え方にreferencedColumnName
設定できるという属性があります@JoinColumn, @PrimaryKeyJoinColumn
。誰かがこれをどこで使用できるかの良い例を挙げてもらえますか?
5 に答える
別のテーブルのデフォルトの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")
「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ドキュメントの永続性セクションのフィールドとして存在しません。このプロパティをどこから取得したかは思い出せませんが、使用したことは覚えています。そのため、このプロパティを例に残しています。
この外部キー列によって参照される列の名前。
デフォルト(単一結合列が使用されている場合にのみ適用されます):参照されるテーブルの主キー列と同じ名前。
Q / A
これはどこで使用されますか?
参照されるテーブルに複合PKがある場合は、参照する列名を指定する必要があります。
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
) です。