Hibernate ManyToOne与OneToOne

时间:2013-08-27 08:22:54

标签: hibernate one-to-one many-to-one

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

@Entity
public class Order {

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

VS

@Entity
public class Order {

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

有什么不同吗?

4 个答案:

答案 0 :(得分:34)

它们在架构上看起来完全相同,但Hibernate Layer存在差异。

如果你尝试这样的话:

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类应该看起来不同。

答案 1 :(得分:5)

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

答案 2 :(得分:0)

这表明通过使用相同的主键可以最好地满足关系的两个方面。这是makes more sense这种方式,因为在@OneToOne关系的情况下,双方只关联一个订单。

答案 3 :(得分:0)

Doctrine ORM documentation of Association Mapping很好地说明了这一点(我不认为这是Hibernate特有的)。

多对一:

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

OneToOne:

现在,请考虑表ProductShipment,而列Product.shipment_idShipment.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);

区别在于UNIQUE INDEX子句,它规定在shipment.id表中不得出现Product两次。这保证了 One ToOne关联。