Foo
とBar
の2つのクラスがあります。データベース内のテーブルは次のようになります。
_|Foo|
|id : INT (PK) | bar_id : INT (PK, FK) |
|Bar|
|id : INT (PK) |
_
通常、私はそれを次のようにマップします:
_@Entity
public class Bar
{
@Id
@Column(name = "id")
private int id;
@OneToMany
private Set<Foo> foo;
}
@Entity
public class Foo
{
@EmbeddedId
private FooPK key;
@MapsId("barId")
@ManyToOne
@JoinColumn(name = "bar_id", referencedColumnName = "id")
private Bar bar;
}
@Embeddable
public class FooPK
{
@Column(name = "id")
private int id;
@Column(name = "bar_id")
private int barId;
}
_
ただし、FooPK
のIDは大まかにマッピングされているため、手動で接続する必要があります。緩いIDの代わりにオブジェクトを使用してマップするソリューションをお勧めします。私は次のことを試しましたが、(もちろん)うまくいきませんでしたが、私が何を達成したいのかがわかると思います:
_@Entity
public class Bar
{
@Id
@Column(name = "id")
private int id;
@OneToMany
private Set<Foo> foo;
}
@Entity
public class Foo
{
@EmbeddedId
private FooPK key;
@MapsId("barId")
@ManyToOne
@JoinColumn(name = "bar_id", referencedColumnName = "id")
@Access(AccessType.FIELD)
private Bar getBar()
{
return key.getBar();
}
}
@Embeddable
public class FooPK
{
@Column(name = "id")
private int id;
@Transient
private Bar bar;
//....
@Column(name = "bar_id")
@Access(AccessType.PROPERTY)
private int getBarId
{
return bar.getId();
}
}
_
後者のソリューションのもう1つの問題は、FooPK
のgetBarId()
メソッドにsetBarId(Int)
メソッドが必要なことです。 IDを使用したオブジェクトの設定は、データアクセス層にアクセスすることで実行できますが、これは(私の意見では)ビジネス/ドメイン/データ層の分離に違反します。
じゃあ何をすればいいの?最初の解決策を使用して、IDを手動で同期しますか、それとも別の(ベスト)プラクティスがありますか?
JPA 2:複合主キークラス の説明を参照して、FooクラスとFooPKクラスに次の変更を加えます。
@Entity
public class Foo {
@EmbeddedId
private FooPK key;
@MapsId("barId") //references EmbeddedId's property
@JoinColumn(name = "bar_id", referencedColumnName = "id")
@ManyToOne
private Bar bar;
}
@Embeddable
public class FooPK {
@Column(name = "id")
private int id;
@Column(name = "bar_id")
private int barId;
}
最初にFIELDアクセスで機能させてから、PROPERTYアクセスを適用することをお勧めします。
じゃあ何をすればいいの?最初の解決策を使用して、IDを手動で同期しますか、それとも別の(ベスト)プラクティスがありますか?
苦痛から身を守る-IDを自動的に生成します。