繁体   English   中英

对@JoinColumn和mappedBy的休眠查询

[英]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)

当保留part1part2 ,Hibernate会为Part生成插入SQL。 Hibernate尚不知道Productid是什么,因此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)

所不同的是,当你坚持order1order2 ,你告诉休眠什么是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM