JPA和Hibernate:一对一映射导致三个选择查询

Rak*_*uri 6 hibernate jpa

JPA 2.0 Hibernate 4.3.5

嗨,

以下是我的OneToOne映射(示例代码假设1个客户只能有1个订单)

class Customer {
    private Order order;
    @OneToOne(mappedBy="customer", fetch=FetchType.LAZY)
    public Order getOrder() { return order; }
    public void setOrder(Order order) { this.order = order ; }
}

class Order {
    private Customer customer;
    @OneToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="cust_id")
    public Customer getCustomer() { return customer; }
    public void setCustomer(Customer customer) { this.customer = customer; }
}

//Calling code
Order order = em.find(Order.class, 4);    // Line 1
System.out.println(order.getCustomer());  // Line 2
</code>
Run Code Online (Sandbox Code Playgroud)

上面的调用代码实际上产生了3个选择语句,即

第1行引起

   select * from order where id = ?      #1
Run Code Online (Sandbox Code Playgroud)

第2行导致以下两个语句

   select * from customer where id = ?   #2
   select * from order where cust_id = ? #3
Run Code Online (Sandbox Code Playgroud)

我的问题:鉴于两端都启用了LAZY提取,它不应该只是两个查询(即#1和#2)吗?

谢谢,拉克什

小智 2

我认为问题在于一对一关系,你不能进行延迟加载,请查看https://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one

由于您在客户之前加载订单对象,因此它将发出接下来的两个查询来加载客户及其一对一关系。

简单地避免此问题的一种可能性是将客户对象定义为可选:

class Customer {
    private Order order;
    @OneToOne(mappedBy="customer", fetch=FetchType.LAZY,**optional=true**)
    public Order getOrder() { return order; }
    public void setOrder(Order order) { this.order = order ; }
}
Run Code Online (Sandbox Code Playgroud)