JPA and Hibernate: one-to-one mapping triggers three select queries

JPA 2.0 Hibernate 4.3.5

Hi,

Below is my OneToOne mapping (with an example code whereby 1 customer can only have 1 order)

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>

Above, the calling code actually leads to 3 ie select statements

Line 1 calling

   select * from order where id = ?      #1

Line 2 calls the following two statements

   select * from customer where id = ?   #2
   select * from order where cust_id = ? #3

My question is: Shouldn't there be only two queries (for example, No. 1 and No. 2), given that the LAZY option is turned on at both ends?

Thank you Rahkesh

+6
source share
4 answers

You have defined both relationships as LAZY.

, Customer , LAZY. LAZY .

, (OneToOne ManyToOne), , LAZY.

EAGER:

@OneToOne(fetch=FetchType.EAGER) // or just @OneToOne
@JoinColumn(name="cust_id")
public Customer getCustomer() { return customer; }

, ? O.o

+3

, --, , https://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one.

, , --.

- customer :

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 ; }
}
+2

- , .

fetchMode LAZY hibernate -. - (id), , - ( ).

, db, - : , cust_id . [ , ]

: -, hibernate , - . . [ , : toString() - .]

fetchMode LAZY "--" . --.

, , - , - - .

+2
source

If you want to solve the problem only in a single query, you have to make an option, "the problem with the request n + 1" allowed JOIN FETCH.

FETCH JOINS as the easiest way to implement and solve the problem with the request (N Time M + 1).

SELECT item FROM ItemRecord
 JOIN FETCH item.costs,
 JOIN FETCH item.notes,
 JOIN FETCH item.stats;

I suggest you this article.

+1
source

All Articles