Vinit89
Vinit89

Reputation: 583

How Session.get method works in hibernate

I am trying to understand that how object initialization works for returned object by Session Get method.Please validate my understanding. When it executes, it checks for object with given identifier in the first level cache and then the Second level cache (If it is configured), If not found then fires the select query to retrieve the data from database. My question is, Does it include associations in select query which are configured for lazy loading or null value is set for such associations in returned object?

If this is case then session.get does not do the complete initialization of the returned object which is contradictory to what is written on most of hibernate tutorials available on web.

Upvotes: 5

Views: 31707

Answers (4)

Amitesh Rai
Amitesh Rai

Reputation: 874

1) Customer entity class that map the T_CUSTOMER DB table:

@Entity
@Table(name= “T_CUSTOMER”)
public class Customer {
    @Id
    @Column (name=“cust_id”)
    private Long id;

    @OneToMany(fetch=FetchType.EAGER)
    @JoinColumn (name=“cid”)
    private Set<Address> addresses;
    …
    …
    …
}

2) Address entity class that map the T_ADDRESS DB table:

@Entity
@Table(name= “T_ADDRESS”)
public class Address {
    // Fields and Properties
}

Consider this Customers table :

----------------------------------------------------------------------------
| Cust_id  | Cust_firstname | Cust_lastname  |  Cust_email  |  Cust_mobile |
----------------------------------------------------------------------------
|   101    |       XXXX     |    YYYYY         |[email protected] |  8282263131  |
----------------------------------------------------------------------------

The Above customers table is having one record with cust_id as 101.

Now Consider this Address Table :

----------------------------------------------------------------------------
| id       |   street    |    suburb     |   city   |  zipcode |    cid    |
----------------------------------------------------------------------------
|   1      |   streetX   |    AreaY      | cityZ    |  54726   |    101    |
----------------------------------------------------------------------------
|   2      |   streetXA  |    AreaYB     | cityZS   |  60660   |    101    |
----------------------------------------------------------------------------

Now When you invoke :

Customer cust = (Customer)session.get(Customer.class, 101);

Then Hibernate will fire a SQL Query Something like :

1). In case of EAGER LOADING :

SELECT * FROM T_CUSTOMER cust JOIN T_ADDRESS add ON cust.cust_id=add.cid

i.e, It will load all the data related to the T_CUSTOMERS table and it's associated tables, which is T_ADDRESS table in this case.

2). I case of LAZY LOADING :

SELECT * FROM T_CUSTOMER WHERE cust_id=101;

So, it only fetches the data corresponding to the T_CUSTOMER table and uses Proxy for the T_ADDRESS table as said above by @Radim Köhler. It will fetch the data from the T_ADDRESS TABLE only when you'll call :

cust.getAddresses();

Upvotes: 0

Ankur Singhal
Ankur Singhal

Reputation: 26067

Simply

When get() method is called, it will directly hit the database, fetch the result and return. If no matching fields are found, it will gladly return null.

Depending on the annotations on references, Lazy or Eager, data will be returned. if Lazy, proxy will be returned instead of null, if Eager, fully initialized object will be returned.

Better to monitor the queries at the backend, for good understanding.

Upvotes: 0

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

To answer the question:

Does it include associations in select query which are configured for lazy loading or null value is set for such associations in returned object?

1) The session.get() will NOT initiate lazy stuff. NEVER. In fact that is the central thought of the design. Otherwise - we would be able to load whole DB in one SHOT (in one JAVA call to session.get())

2) And also there WILL NOT be null instead. Each reference or collection will be represented by proxy. This is the way how we can avoid to load compelte DB in one shot (all stuff initialized with one method get). Because each proxy is in fact a promise - once we will touch it... it will load the real data.

And so on. So get is very safe way how to recieve as few data as was configured....

Upvotes: 1

Manoj Kumar
Manoj Kumar

Reputation: 757

Hibernate Session provide different methods to fetch data from database. Two of them are – get() and load(). get() returns the object by fetching it from database or from hibernate cache. when we use get() to retrieve data that doesn’t exists, it returns null, because it try to load the data as soon as it’s called.

  • We should use get() when we want to make sure data exists in the database.

For Example :

In a Stock application , Stock and StockTransactions should have a “one-to-many” relationship, when you want to save a stock transaction, it’s common to declared something like below.

       Stock stock = (Stock)session.get(Stock.class, new Integer(2));
       StockTransaction stockTransactions = new StockTransaction();
       //set stockTransactions detail
       stockTransactions.setStock(stock);        
       session.save(stockTransactions);

Output :

Hibernate: 
select ... from mkyong.stock stock0_ 
where stock0_.STOCK_ID=?
Hibernate: 
insert into mkyong.stock_transaction (...) 
values (?, ?, ?, ?, ?, ?)

In session.get(), Hibernate will hit the database to retrieve the Stock object and put it as a reference to StockTransaction.

Upvotes: 2

Related Questions