我看不出多对一关系与OneToOne关系的架构有什么不同:
@Entity
public class Order {
@ManyToOne
@JoinColumn(nullable = false)
private Address address;
VS
@Entity
public class Order {
@OneToOne
@JoinColumn(nullable = false)
private Address address;
有什么不同吗?
答案 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特有的)。
考虑表User
和Address
,而列User.address_id
与Address.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);
现在,请考虑表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);
区别在于UNIQUE INDEX
子句,它规定在shipment.id
表中不得出现Product
两次。这保证了 One ToOne关联。