Java Hibernate对@JoinColumn和mappedBy的查询
我试图理解在Hibernate中使用@JoinColumn与使用@OneToMany映射的mappedBy属性时生成的DML查询的区别 如果我将java类定义为:Java Hibernate对@JoinColumn和mappedBy的查询,java,hibernate,jpa,Java,Hibernate,Jpa,我试图理解在Hibernate中使用@JoinColumn与使用@OneToMany映射的mappedBy属性时生成的DML查询的区别 如果我将java类定义为: @Entity public class Product { @Id String serialNumber; @OneToMany @JoinColumn(name = "PRODUCT_ID") Set<Part> parts = new HashSet<Part>(); } @Ent
@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;
}
@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();
}
}
现在,如果我将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;
}
@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在第一种情况下需要插入和更新,在第二种情况下只需要插入查询?请解释。在使用
@JoinColumn
的第一个版本中,您需要在产品
之前先保存部分
,例如:
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)
@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;
}
当持久化part1
和part2
时,Hibernate为部分
生成插入SQL。Hibernate不知道Product
的id
是什么,但是Product\u id
列将为空
当持久化产品
时,Hibernate为产品
生成插入SQL。现在Hibernate知道为产品生成的id
是什么。然后,Hibernate发出更新SQL,通过为PRODUCT\u 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
时,您告诉Hibernate该订单的客户是什么。相关客户的id保存在每个订单中
如果您希望使用类似于第一个版本的@JoinColumn
,但不需要额外的SQL更新,您可以使用@ElementCollection
,例如:
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)
@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;
}
@实体
公共类产品{
@Id@GeneratedValue
字符串序列号;
@元素集合
Set parts=new HashSet();
}
@实体
公共课部分{
@Id@GeneratedValue
int-id;
字符串部分名;
}
上面的映射将生成一个额外的关系表,如product\u part