Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate one-to-one loads eagerly always

Tags:

java

hibernate

I have an Employee and Address with one-to-one bi-directional mapping:

@Entity
public class Employee {
    @Id
    @Column(name = "EMP_ID")
    private long id;

    private String firstName;
    private String lastName;
    private double salary;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ADDRESS_ID")
    private Address address;
}

Below is my address entity:

@Entity
public class Address {
    @Id
    @Column(name = "ADDRESS_ID")
    private long id;

    private String street;
    private String city;
    private String province;
    private String country;
    private String pinCode;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "address")
    private Employee owner;
}

In Address I have set Fetch type as Lazy. So if I get an address then I am expecting hibernate to run select query on address only, but I see in logs that it is trying to get Employee also.

Below is my HQL query:

List<Address> emps = session.createQuery("from Address where id=20").list();

These are the queries run by Hibernate:

Hibernate: 
    /* 
from
    Address 
where
    id=20 */ select
        address0_.ADDRESS_ID as ADDRESS_1_0_,
        address0_.city as city2_0_,
        address0_.country as country3_0_
    from
        Address address0_ 
    where
        address0_.ADDRESS_ID=20
Hibernate: 
    /* load Employee */ select
        employee0_.EMP_ID as EMP_ID1_1_0_,
        employee0_.ADDRESS_ID as ADDRESS_5_1_0_,
        employee0_.firstName as firstNam2_1_0_,
        employee0_.lastName as lastName3_1_0_
    from
        Employee employee0_ 
    where
        employee0_.ADDRESS_ID=?

Why hibernate loads Employee eagerly even when I set its fetching strategy as LAZY.

like image 336
learner Avatar asked Dec 27 '16 17:12

learner


People also ask

What is eager loading in Hibernate?

Eager Loading is a design pattern in which data initialization occurs on the spot. Lazy Loading is a design pattern that we use to defer initialization of an object as long as it's possible.

How can we avoid eager fetch in Hibernate?

First one is to create entity graph and including that in graph. So you would fetch data with your graph and that would be it. No more additional sql queries to fetch eager collection. Second solution is to create entity for same table but with everything marked lazy.

Which is better lazy loading or eager loading?

Eager Loading. Eager loading generates all web page content as soon as possible, while lazy loading delays the display of non-essential content.

What is the difference between FetchType lazy and eager?

LAZY: It fetches the child entities lazily i.e at the time of fetching parent entity it just fetches proxy(created by cglib or any other utility) of the child entities and when you access any property of child entity then it is actually fetched by hibernate. EAGER: it fetches the child entities along with parent.


2 Answers

This great article describes the problem and a possible solution:

https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/

Possible solution: It must be a one-directional relationship from child to parent. The parent cannot have a @OneToOne field to access the child because:

"For every managed entity, the Persistence Context requires both the entity type and the identifier, so the child identifier must be known when loading the parent entity, and the only way to find the associated {child} primary key is to execute a secondary query."

Second solution: Use @OneToMany instead. Don't use @OneToOne because it has this complicated, subtle, quirky problem. You can alter the code to only allow one-to-one access and optionally add a unique key to enforce 1-1.

like image 172
Curtis Yallop Avatar answered Sep 30 '22 20:09

Curtis Yallop


Lazy loading on one-to-one mapping is possible either by

  1. Setting optional=false (If its not nullable) or
  2. JoinColumn (not on PK and might require schema change)

You can refer to this link for moreinfo.

Explanation : You can refer to explanation link for detailed explanation about this.

like image 45
Kishore Bandi Avatar answered Sep 30 '22 18:09

Kishore Bandi