Hibernate ManyToOne与OneToOne

DD.*_*DD. 36 hibernate one-to-one many-to-one

我看不出多对一关系与OneToOne关系的架构有什么不同:

@Entity
public class Order {

    @ManyToOne
    @JoinColumn(nullable = false)
    private Address address;
Run Code Online (Sandbox Code Playgroud)

VS

@Entity
public class Order {

    @OneToOne
    @JoinColumn(nullable = false)
    private Address address;
Run Code Online (Sandbox Code Playgroud)

有什么区别吗?

小智 37

它们在模式上看起来完全相同,但Hibernate Layer有所不同.

如果您尝试这样的事情:

Address address = new Address();
Order order1 = new Order();
order1.setAddress(address);
Order order2 = new Order();
order2.setAddress(address);
save();
Run Code Online (Sandbox Code Playgroud)

一切都会变好.但是,保存后,如果你尝试获得订单:

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

@ManyToOne case:
SUCCESS
Run Code Online (Sandbox Code Playgroud)

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

  • 对于任何未来阅读paulek帖子的人:你的权利必须__ soust以便得到那个错误.如果只有单向关系,则不会弹出该错误.如果您具有双向关系,则只有选择加入取值订单的地址才会生成该错误. (2认同)

ago*_*dev 6

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

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

一个例子:

多对一:

考虑这些表UserAddress并且该列User.address_id与该列具有多对一关联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); 
Run Code Online (Sandbox Code Playgroud)

一对一:

现在,考虑表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);
Run Code Online (Sandbox Code Playgroud)

唯一的区别是指令规定表中UNIQUE INDEX不得出现两次。这保证了一对一关联。shipment.idProduct


JB *_*zet 5

address_idOneToOne关联的情况下,通常应该在连接列上有唯一约束,以保证只有一个订单可以具有给定地址.