多対1の関係とOneToOneの関係のスキーマに違いはありません。
@Entity
public class Order {
@ManyToOne
@JoinColumn(nullable = false)
private Address address;
対
@Entity
public class Order {
@OneToOne
@JoinColumn(nullable = false)
private Address address;
違いはありますか?
それらはスキーマではまったく同じに見えますが、Hibernateレイヤーでは違いがあります。
そのようなことをしようとすると:
Address address = new Address();
Order order1 = new Order();
order1.setAddress(address);
Order order2 = new Order();
order2.setAddress(address);
save();
すべて大丈夫です。しかし、保存してからOrderを取得しようとすると、次のようになります。
@OneToOne case:
org.hibernate.HibernateException: More than one row with the given identifier was found: 1
@ManyToOne case:
SUCCESS
もちろん、Addressクラスはどちらの場合でも異なって見えるはずです。
OneToOneアソシエーションの場合、通常、address_id
結合列には一意の制約があり、1つのOrderのみが特定のアドレスを持つことができるようにする必要があります。
これは 関連マッピングのDoctrine ORMドキュメント (Hibernateに固有のものではないと思います)でうまく説明されています。
列User.address_id
にAddress.id
列へのManyToOneアソシエーションがある間、テーブルUser
およびAddress
を検討してください。これはSQLです。
CREATE TABLE User (
id INT AUTO_INCREMENT NOT NULL,
address_id INT DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE Address (
id INT AUTO_INCREMENT NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE User ADD FOREIGN KEY (address_id) REFERENCES Address(id);
ここで、テーブルProduct
およびShipment
を検討します。一方、列Product.shipment_id
には、Shipment.id
列へのOneToOne(単方向)関連付けがあります。これはSQLです。
CREATE TABLE Product (
id INT AUTO_INCREMENT NOT NULL,
shipment_id INT DEFAULT NULL,
UNIQUE INDEX UNIQ_6FBC94267FE4B2B (shipment_id),
PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE Shipment (
id INT AUTO_INCREMENT NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE Product ADD FOREIGN KEY (shipment_id) REFERENCES Shipment(id);
違いは、Product
テーブルでUNIQUE INDEX
が2回発生してはならないことを示すshipment.id
句です。これにより、OneToOne関連付けが保証されます。
これは、リレーションシップの両側が同じ主キーを持つことで最適に機能することを示しています。 @OneToOne
関係の場合、両側が1つだけの注文に関連付けられるため、これは もっと理にかなっています この方法です。