我试图理解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,0) not null, orderNumber number(10,0) not null, customer_id number(10,0), orders_index number(10,0), 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,0) not null, primary key (id))
Hibernate: create table Customer_TBL_ORDER (Customer_id number(10,0) not null, orders_id number(10,0) not null, orders_index number(10,0) not null, primary key (Customer_id, orders_index))
Hibernate: create table TBL_ORDER (id number(10,0) not null, orderNumber number(10,0) not null, customer_id number(10,0), 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会创建一个额外的表?这个属性是如何控制的?为什么我们有一个额外的唯一键约束orders_idCustomer_TBL_ORDER表中的列?
现在,如果我试图保存一个客户及其订单,我会得到以下DML操作:
Hibernate: insert into Customer (id) values (?)
Hibernate: insert into TBL_ORDER (customer_id, orderNumber, id) values (?, ?, ?)
Hibernate: insert into Customer_TBL_ORDER (Customer_id, orders_index, orders_id) values (?, ?, ?)
为什么在这种情况下,我们没有一个额外的更新查询相比,我已经声明了mappdBy属性的情况下?
此行为mappdBy
仅指示此端中的实体是关系的反义词,并且所有者驻留在其他实体中。
我建议你使用这个链接
OneToMany有两种主要的方法可以在数据库中实现。
如果您保留一个OneToMany
映射并将其设为默认值,它将默认使用一个关系表,这似乎是您想要的。如果不希望使用联接表,可以指定一个JoinColumn
,它设置外键关系,就像OneToOne
,但方向相反-它告诉提供者目标表中的哪个字段指向该实体的主键。但通常目标外键映射到目标实体中-毕竟它是一个manytone
,因此mappedby
用于指定此OneToMany
应使用目标实体中已定义的关系。
在这种情况下,mappedBy=customer
告诉它查看订单实体中的customer
属性映射。在那里,它发现customer有一个manytomy
映射,其中有一个默认的joinColumncustomer\u id
,它也用于OneToMany
。因为它已经映射到订单实体中,OneToMany
是只读的。这确保了如果这两个关系不同步,JPA
有一个始终信任的方面,并用于设置数据库字段。
这很正常。
使用mappedBy
,您可以直接告诉Hibernate/JPA一个表拥有该关系,因此它被存储为该表的一列。
如果没有,关系是外部的,Hibernate/JPA需要创建另一个表来存储关系。
示例:
问题
有几个答案
在普通JDBC中,您将创建两个表:
Questions(Question_ID, ...);
Answers(Answer_ID, Question_ID, ...);
其中Question\u ID
是外键引用Question。问题_ID
。
至于另一种情况,我没有一个真正的情况,因为几乎每次都有多对多的唯一约束(例如:一个问题
可能有几个答案
,而答案
可能物理上有几个问题
,但对于任何问题
)只出现一次。
根据Hibernate留档,注释的解释如下: 在嵌入式id对象中,关联表示为关联实体的标识符。但您可以通过@MapsId注释将其值链接到实体中的常规关联。@MapsId值对应于包含关联实体标识符的嵌入式id对象的属性名称。在数据库中,这意味着客户。用户和客户ID。userId属性共享相同的基础列(本例中为user\u fk)。 它还说: 虽然JPA不支持Hibernate,但它允许您将关联直接放置
nexr@Entity公共类产品{ 错误:
我有4个表kode_pos、korwil、user和WAFAT。在Korwil类中,它保存来自user的外键,并将主键交给kode_pos,这意味着在Korwil类@OneToOne和@OneToMany中有两个映射, 我有个错误 org.hibernate.AnnotationException:在:org.ppbni.splatter.model.useradmin.korwil中未知mapp
问题内容: 需要使用一对多和多对一关系。这是我对象中的双向关系,因此我可以从任一方向来回移动。是推荐的解决方法,但是,我听不懂。有人可以解释: 推荐的使用方式是什么? 它解决什么目的? 就我的示例而言,这是带有注释的类: 拥有许多 许多 属于一个 A 航空公司: 航空公司航班: 编辑: 数据库模式: AirlineFlights具有idAirline作为ForeignKey,而Airline没有i
问题内容: 我试图了解JPA 中注释的属性。我在下面的示例中创建了一个客户具有订单列表的示例: 现在,当我使用Hibernate生成表时,我看到Hibernate仅创建了2个表: 另外,如果我尝试保存客户和一些订单,我会在下面看到由Hibernate生成的DML语句: 为什么Hibernate试图在TBL_ORDER中插入和更新记录,而不仅仅是运行单个插入查询? 现在,如果我删除mapledBy属
Hibernate留档在@BatchSize上提供了一些信息,如下所示: @BatchSize指定一个“批量大小”,用于按标识符获取此类实例。尚未加载的实例一次加载一个批大小(默认值为1)。 我不清楚这个注释的目的是什么,什么时候我们需要使用它。请帮助我理解何时使用这个注释。