[英]Hibernate queries for @JoinColumn and mappedBy
我试图了解如果我使用@JoinColumn与Hibernate中的@OneToMany映射的mappingBy属性相比,生成的DML查询中的差异。
如果我的java类定义为:
@Entity
public class Product {
@Id
String serialNumber;
@OneToMany
@JoinColumn(name = "PRODUCT_ID")
Set<Part> parts = new HashSet<Part>();
}
@Entity
public class Part {
@Id
@GeneratedValue
int id;
String partName;
}
然后我保存产品和零件的ID,然后休眠生成插入并更新查询:
Hibernate: insert into Product (serialNumber) values (?)
Hibernate: insert into Part (partName, id) values (?, ?)
Hibernate: update Part set PRODUCT_ID=? where id=?
现在,如果我将Java类定义为:
@Entity
public class Customer {
@Id
@GeneratedValue
private Integer id;
@OneToMany(mappedBy = "customer")
private List<Order> orders;
}
@Entity
@Table(name="TBL_ORDER")
public class Order {
@Id
@GeneratedValue
private Integer id;
private int orderNumber;
@ManyToOne
private Customer customer;
@Override
public String toString() {
return id.toString();
}
}
然后,Hibernate仅生成没有任何更新的插入查询:
Hibernate: insert into Customer (id) values (?)
Hibernate: insert into TBL_ORDER (customer_id, orderNumber, id) values (?, ?, ?)
如果我的实体之间的关系只有一对多,那么为什么冬眠需要在第一种情况下插入和更新,而在第二种情况下只需要插入查询? 请解释。
在使用@JoinColumn
的第一个版本中,您需要将Part
first保留在Product
之前,例如:
Part part1 = new Part()
Part part2 = new Part()
em.persist(part1)
em.persist(part2)
Product product = new Product()
product.parts.add(part1)
product.parts.add(part2)
em.persist(product)
当保留part1
和part2
,Hibernate会为Part
生成插入SQL。 Hibernate尚不知道Product
的id
是什么,因此PRODUCT_ID
列将为null。
保留product
,Hibernate会为Product
生成插入SQL。 现在,Hibernate知道Product
生成的id
是什么。 然后,Hibernate发出更新SQL,以通过为PRODUCT_ID
列设置适当的值来更新Part
的现有记录。
在使用mappedBy
的第二个版本中,您将像这样持久化它们:
Customer customer = new Customer()
em.persist(customer)
Order order1 = new Order() // using `Order` as entity name is not always valid because `Order` it is often confused with SQL clause
order1.setCustomer(customer)
em.persist(order1)
Order order2 = new Order()
order2.setCustomer(customer)
em.persist(order2)
所不同的是,当你坚持order1
和order2
,你告诉休眠什么是Customer
对于Order
。 相关客户的ID保存在每个订单中。
如果要使用@JoinColumn
作为第一个版本,但又没有额外的SQL更新,则可以使用@ElementCollection
,例如:
@Entity
public class Product {
@Id @GeneratedValue
String serialNumber;
@ElementCollection
Set<Part> parts = new HashSet<Part>();
}
@Entity
public class Part {
@Id @GeneratedValue
int id;
String partName;
}
上面的映射将生成一个额外的关系表,例如product_part
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.