46

我看不出多对一关系与 OneToOne 关系的架构有任何区别:

@Entity
public class Order {

    @ManyToOne
    @JoinColumn(nullable = false)
    private Address address;

对比

@Entity
public class Order {

    @OneToOne
    @JoinColumn(nullable = false)
    private Address address;

有什么区别吗?

4

4 回答 4

51

它们在模式上看起来完全一样,但在休眠层上有区别。

如果你尝试这样的事情:

Address address = new Address();
Order order1 = new Order();
order1.setAddress(address);
Order order2 = new Order();
order2.setAddress(address);
save();

一切都会变好。但是,如果您尝试获取订单,则保存后:

@OneToOne case:
org.hibernate.HibernateException: More than one row with the given identifier was found: 1

@ManyToOne case:
SUCCESS

当然,您的 Address 类在这两种情况下应该看起来不同。

于 2013-08-27T11:09:28.407 回答
7

在 OneToOne 关联的情况下,连接列通常应该有一个唯一约束address_id,以保证只有一个 Order 可以具有给定地址。

于 2013-08-27T08:25:50.690 回答
3

TL;DR:乍一看,架构可能看起来相同,但 OneToOne 可能有一个额外的UNIQUE INDEX约束。这保证了One ToOne 关联。

关联映射的 Doctrine ORM 文档很好地说明了这一点(我不认为它特定于 Hibernate)。

一个例子:

多对一:

考虑这些表UserAddress而列与该列User.address_id具有 ManyToOne 关联Address.id。这将是 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); 

一对一:

现在,考虑表ProductShipment,而列与列Product.shipment_id具有 OneToOne(单向)关联Shipment.id。这将是 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);

唯一的区别是UNIQUE INDEX指示表中不能shipment.id出现两次的指令Product。这保证了One ToOne 关联。

于 2018-03-24T14:55:51.523 回答
0

这表明关系的双方最好使用相同的主键。这种方式更有意义,因为在关系的情况下,双方都关联一个且只有一个订单@OneToOne

于 2017-08-31T13:14:33.083 回答