Shelly
Shelly

Reputation: 1035

How proxy loads the lazy property in Hibernate/JPA

Well, my doubt is very simple: For best performance is recommended that use always lazy initialization in property that I don't need to use (this is obvious). So, imagine the following class:

  @Entity
  public class Person{
    @Column
    private String name;
    @ManyToOne(fetch = FetchType.Lazy)
    @JoinColumn(name = "id_type")
    private TypePerson type;
 }

In my main class I call the Person with "type" attribute not initialized, like bellow:

 public void init(){
    //in this point "type" attribute is not initialized
    Person person = dao.find("Select * from Person where id = 12");

    //proxys work here to get description of "type" attribute
    System.out.println(person.getType().getDescription());
  }

So, I get a simple Person object from dataBase, and print on console the type of person. In this moment Proxy CGLIB works and do your magic, and everything works fine.

But here I go my question:

1 - When I request the "getType()" the Hibernate (or another mechanism) make a SQL Query behind the scenes ? Like: "SELECT * FROM TypePerson where id = 3".

If answer is yes: This method to get value of a property can be very painful, because I think Hibernate goes everytime in database to get this information behind the scenes.

If answer is no: How Proxy know the value of property if this wasn't loaded from dataBase ?

Upvotes: 2

Views: 5377

Answers (2)

JB Nizet
JB Nizet

Reputation: 691775

  1. Actually, it goes to the database when the getDescription() method is called on the proxy returned by person.getType().
  2. It goes to the database only if you call a method on the proxy, i.e. when you actually want to load the state of the entity wrapped by the proxy. It does it only once in the session lifetime. The next call to a method of the proxy won't go to the database anymore, because the proxy will already be ininitailized by the previous method call. And of course it needs to query the database. How could you get data from the database without querying it? The advantage of lazy proxies is precisely that it retrieves the state only if, and when needed. If you know in advance that you'll need the person type, then either don't use a lazy proxy, or use a query that loads the person and its type ina single query. It's up to you.

Upvotes: 1

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279990

When you call

person.getType().getDescription()

if person is referencing a Hibernate proxy that hasn't been initialized, then, yes, it will issue an SQL query to retrieve the target entity's field values.

This method to get value of a property can be very painful, because i think Hibernate goes everytime in database to get this information behind the scenes.

It will only go once for each proxy. When it goes the first time, it will set a flag on the proxy that indicates that it is initialized and therefore the underlying target entity has the right value. You don't need to go back to the database if it has all its values loaded.

This is not exactly how Hibernate creates its proxies, but it is a good read: Proxy Pattern.

Upvotes: 3

Related Questions