我试图理解在使用@JoinColumn时生成的DML查询与Hibernate中@OneToMany映射的mappedBy属性相比的差异。
如果我将我的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生成插入并更新查询:
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 (?, ?, ?)
如果我的实体之间的关系只有一对多,那么为什么hibernate需要插入&amp;第一种情况的更新,只在第二种情况下插入查询?请解释一下。
答案 0 :(得分:1)
在使用@JoinColumn
的第一个版本中,您需要先在Part
之前保留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不知道id
的{{1}}是什么,所以Product
列将为空。
当持久化PRODUCT_ID
时,Hibernate会为product
生成插入SQL。现在Hibernate知道Product
生成的id
是什么。然后,Hibernate通过为Product
列设置适当的值来发布更新SQL以更新Part
的现有记录。
在使用PRODUCT_ID
的第二个版本中,您可以像以下一样坚持:
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
时,您告诉Hibernate order2
的{{1}}是什么。相关客户的ID保存在每个订单中。
如果您希望使用Customer
的第一个版本,但没有额外的更新SQL,则可以使用Order
,例如:
@JoinColumn
上面的映射将生成一个额外的关系表,例如@ElementCollection
。