我试图理解JPA中@OneToMany注释的mappedBy属性.我创建了下面的例子,其中客户有一个订单列表:
@Entity public class Customer { @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } private Integer id; @OneToMany(mappedBy="customer") @OrderColumn(name="orders_index") public List<Order> getOrders() { return orders; } public void setOrders(List<Order> orders) { this.orders = orders; } private List<Order> orders; } @Entity @Table(name="TBL_ORDER") public class Order { @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } private Integer id; public int getOrderNumber() { return orderNumber; } public void setOrderNumber(int orderNumber) { this.orderNumber = orderNumber; } private int orderNumber; @ManyToOne public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } private Customer customer; }
现在当我使用Hibernate生成表时,我看到Hibernate只创建了2个表:
Hibernate: create table Customer (id number(10,0) not null,primary key (id)) Hibernate: create table TBL_ORDER (id number(10,orderNumber number(10,customer_id number(10,0),orders_index number(10,primary key (id)) Hibernate: alter table TBL_ORDER add constraint FK_nt24krtgqwcsynosqgk4jkvfv foreign key (customer_id) references Customer
另外如果我尝试保存一个客户和一些订单我看到下面由Hibernate生成的DML语句:
Hibernate: insert into Customer (id) values (?) Hibernate: insert into TBL_ORDER (customer_id,orderNumber,id) values (?,?,?) Hibernate: update TBL_ORDER set orders_index=? where id=?
为什么hibernate尝试插入和更新TBL_ORDER中的记录,而不是只运行一个插入查询?
现在如果我删除mappedBy属性并尝试生成这些表,那么这次我看到3个表:
Hibernate: create table Customer (id number(10,primary key (id)) Hibernate: create table Customer_TBL_ORDER (Customer_id number(10,orders_id number(10,primary key (Customer_id,orders_index)) Hibernate: create table TBL_ORDER (id number(10,primary key (id)) Hibernate: alter table Customer_TBL_ORDER add constraint UK_sw94jktvh72tripj876s31052 unique (orders_id) Hibernate: alter table Customer_TBL_ORDER add constraint FK_sw94jktvh72tripj876s31052 foreign key (orders_id) references TBL_ORDER Hibernate: alter table Customer_TBL_ORDER add constraint FK_f03up2h945cg0dcbo2pdb1d3c foreign key (Customer_id) references Customer Hibernate: alter table TBL_ORDER add constraint FK_nt24krtgqwcsynosqgk4jkvfv foreign key (customer_id) references Customer
为什么hibernate在这种情况下创建一个附加表? mappedBy属性如何控制?为什么我们在Customer_TBL_ORDER表中的orders_id列上有一个附加的唯一键约束?
现在如果我尝试保存一个客户和它的订单我得到以下DML操作:
Hibernate: insert into Customer (id) values (?) Hibernate: insert into TBL_ORDER (customer_id,?) Hibernate: insert into Customer_TBL_ORDER (Customer_id,orders_index,orders_id) values (?,?)
解决方法
这是正常现象
使用mappedBy,你直接告诉Hibernate / JPA一个表拥有关系,因此它被存储为该表的一列.
没有,关系是外部的,Hibernate / JPA需要创建另一个表来存储关系.
例:
一个stackoverflow问题有几个答案.
答案由唯一一个问题所有.
在简单的JDBC中,您将创建两个表:
Questions(Question_ID,...); Answers(Answer_ID,Question_ID,...);
Where Question_ID是外键引用Question.Question_ID.
对于另一种情况,我没有真实的情况,因为几乎每次都有许多到一个独特的约束(例如:一个问题可能有几个答案,并且答案可能实际上有几个问题,但只出现一次任何问题).