Hibernate ManyToOne vs OneToOne

孤街浪徒 提交于 2019-11-28 18:36:47

They look exactly the same on schema but there is difference on Hibernate Layer.

If you try something like that:

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

Everything will be OK. But, after save if you try get Order:

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

@ManyToOne case:
SUCCESS

Of course, your Address class should looks different in both cases.

There should normally be a unique constraint on the address_id join column in the case of a OneToOne association, to guarantee that only one Order can have a given address.

Progster219

This indicates both sides of the relationship are best served by having the same primary key. It makes more sense this way since both sides are associated one and only one order in the case of the @OneToOne relationship.

This is nicely illustrated by the Doctrine ORM documentation of Association Mapping (I don't think it's specific to Hibernate).

ManyToOne:

Consider the tables User and Address while the column User.address_id has a ManyToOne association to the Address.id column. This would be the 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:

Now, consider the tables Product and Shipment, while the column Product.shipment_id has a OneToOne (unidirectional) association to the Shipment.id column. This would be the 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);

The difference is the UNIQUE INDEX clause which dictates there must not be a shipment.id occuring twice in the Product table. This guarantees the OneToOne association.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!