• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Hibernate load vs get, confused on Hibernate Proxies too

 
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello All

I am newbee to hibernate and wrote a sample application to find out difference between load and get.

What i analyzed was
load method uses lazy fetching and load method returns proxies
get method uses eager fetching and get method doesn't return proxies

1)Would like to know whether hibernate creates proxies only during lazy initialization...or for every scenario when a record is fetched from database hibernate creates proxies irrespective of type of fetching strategy?
I Mean when does hibernate uses/creates proxies?

And one other difference was with in same session

2) I used load method to fetch same record assuming that first time when load method is called it loads data from database,put data in an object and set it in cache associated with session,when i called load method for second time for same record,it should fetch from cache thus avoiding a database hit .So only one select sql even though we called load method twice. It is perfect

3) But when i used get method with in same session twice to fetch same record,as per get method API,it has to fetch data directly from database without checking cache even though same object was loaded earlier into cache,which means there should be 2 sqls.But with in same session,when i call get method for second time it didn't hit database directly instead it fetched data from cache.So i couldn't get exact underlying point ,can some one give me a clear understanding of this?

4)And one more thing when a session is closed can we able to get object from cache?Because in case of get method,say for example i fetched an Employee record from database.I closed session.After closing session still i can get name of Employee.So is it possible to do so?What i understood was for every record retrieved from database hibernate creates object and store object in cache associated with session.So does object exist as long as session is avaialble or even after session is closed as in case of get method.
 
Ranch Hand
Posts: 108
Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Shekhar,

Welcome to the Ranch

1. By default, hibernate creates run-time proxies. It loads the objects as a proxy unless a fetch mode is specified or set to false.
2. load() always retrieves proxy objects. If called more than once within same session, it reads data from persistent context cache.
3. That's because once the object is loaded in cache, the next subsequent calls perform repeatable read.
4. Yes, you can read it. Although the state of this object changes from persistent to detached.
 
Shekar Chandu
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Mishra,
Thanks for reply.
But still have following doubts

1) Hibernate default fetching strategy
I used get method to retrieve a record from database and print the class name and this was output
Publisher class name: class com.sss.hib.Publisher (Normal Class)

I used load method to retrieve a record from database and print the class name and this was output
Publisher class name: class com.sss.hib.Publisher_$$_javassist_0 (Proxy Class)

Hibernate default fetch mode is eager right.
So from output,get method which uses eager fetching doesn't load proxy right,so here hibernate is not creating any default run time proxies right.Please correct me if iam wrong.

So the whole concept of run time proxies is,they get created if lazy loading is disabled right ( means lazy set to false). Please correct me if iam wrong.

2)Regarding Cache associated with session
Even though session is closed ,application can still use cache associated with session.Closing session means further we don't have connection to database right.
So using get method to retrieve Employee object we can get name of employ even when session is closed.But when load method is used, outside session when we try to get employ
name we cant because there is no database connection .
Hence LazyInitilizationException.

3)Difference between get and load

If both get and load return data from cache after first call.Then whats difference between them except that load throws ObjectNotFoundException and get returns Null.
As a performance point of view i read in a document like if a object is being used more times in a transaction retrieve object using load method rather than get method
as former retrieves data from cache and latter from database for every call to fetch record.
Can you please clear me on this

 
T Mishra
Ranch Hand
Posts: 108
Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
fetch mode is used to load objects in association.
fetch strategy is used to load data from database for entities.

EAGER - means load all the associated items whenever the entity is loaded.
LAZY - loads only the proxy object.

The entity can be retrieved in 2 ways.
load() - returns the proxy object with an identifier.
get() - returns the complete object from database.
By default, hibernate loads all entities by lazy fetching strategy. It can be disabled by setting lazy = false on Entity definition.
In real time applications, entity is mostly associated with other items (mapped by colledtions)
By default, whenever an entity is loaded, only the proxy objects of the associated items are retrieved into the persistent context. This means, lazy = true.
but in case you want to load the associated objects - you can set fetch mode to EAGER to retrieve all associated objects of that entity. e.g.

1. covered above.
2. correct
3. Correct. You've got the difference correct. Performance - Its upto you to optimize the fetching mode / startegy. Yes, get() hits the database everytime its invoked. but then there are some cases where you'd want eager load too.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A quick question, lets say if there is no record in database with Id(100) for example, and if we use load() method then we will get the result as 100, which is not correct.
So if this is case then we will always end up in getting the records even though the records does not exist in database.
Can anyone please tell me in real world as where this will have an impact on get or load methods or in what scenarios we will be using get() method or load().
I am now aware of performance but would like to know what if in case of data retrievals kind of stuff I am looking.
I would really appreciate if anyone let me know the difference in terms of the Application perspective, I am bit interested in knowing the depth of the details.

Thanks,
Praveen
 
Shekar Chandu
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Mishra,

Iam reading Pro JPA 2 and in chapter 7 of book we have the following lines

"The result type of a select query cannot be a collection; it must be a single valued object such as an entity instance
or persistent field type. Expressions such as e.phones are illegal in the SELECT clause because they would result in
Collection instances (each occurrence of e.phones is a collection, not an instance)
. Therefore, just as with SQL and
tables, if we want to navigate along a collection association and return elements of that collection, we must join the
two entities together. In the following code, a join between Employee and Phone entities is implicitly applied in order
to retrieve all the cell phone numbers for a specific department:

SELECT p.number
FROM Employee e, Phone p
WHERE e = p.employee AND
e.department.name = 'NA42' AND
p.type = 'Cell'"



For the same above Employee and Phone example if i write a query

select e.phones from Employee e,

then i didnt get any errors and i got the output correctly as follows

Hibernate:
select
phones1_.id as id3_,
phones1_.employee_id as employee4_3_,
phones1_.number as number3_,
phones1_.type as type3_
from
JPA.Employee employee0_
inner join
JPA.Phone phones1_
on employee0_.id=phones1_.employee_id
1 Phone[id=1,number=(212)555-1234,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@24802480]
2 Phone[id=2,number=(212)555-9843,type=Home,employee=com.ibm.sample.jpa.entitybeans.Employee@24802480]
3 Phone[id=3,number=(315)555-6253,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@26422642]
4 Phone[id=4,number=(516)555-9837,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@27882788]
5 Phone[id=5,number=(516)555-2034,type=Cell,employee=com.ibm.sample.jpa.entitybeans.Employee@27882788]
6 Phone[id=6,number=(650)555-7583,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@367e367e]
7 Phone[id=7,number=(650)555-5345,type=Home,employee=com.ibm.sample.jpa.entitybeans.Employee@367e367e]
8 Phone[id=8,number=(650)555-9386,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@606e606e]
9 Phone[id=9,number=(650)555-4885,type=Cell,employee=com.ibm.sample.jpa.entitybeans.Employee@606e606e]
10 Phone[id=10,number=(650)555-3836,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@61b661b6]
11 Phone[id=11,number=(650)555-0985,type=Home,employee=com.ibm.sample.jpa.entitybeans.Employee@61b661b6]
12 Phone[id=12,number=(650)555-1946,type=Cell,employee=com.ibm.sample.jpa.entitybeans.Employee@61b661b6]
13 Phone[id=13,number=(650)555-4759,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@62fc62fc]
14 Phone[id=14,number=(650)555-4757,type=Home,employee=com.ibm.sample.jpa.entitybeans.Employee@62fc62fc]
15 Phone[id=15,number=(650)555-6753,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@62fc62fc]
16 Phone[id=16,number=(585)555-0693,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@28d028d0]
17 Phone[id=17,number=(585)555-3098,type=Home,employee=com.ibm.sample.jpa.entitybeans.Employee@28d028d0]
18 Phone[id=18,number=(585)555-1457,type=Cell,employee=com.ibm.sample.jpa.entitybeans.Employee@28d028d0]
19 Phone[id=19,number=(650)555-9838,type=Office,employee=com.ibm.sample.jpa.entitybeans.Employee@646e646e]
20 Phone[id=20,number=(650)555-2346,type=Home,employee=com.ibm.sample.jpa.entitybeans.Employee@646e646e]
21 Phone[id=21,number=(650)555-9874,type=Cell,employee=com.ibm.sample.jpa.entitybeans.Employee@646e646e]

which is quite opposite to what the line above in chapter7 of book "The result type of a select query cannot be a collection; it must be a single valued object such as an entity instance
or persistent field type. Expressions such as e.phones are illegal in the SELECT clause because they would result in
Collection instances (each occurrence of e.phones is a collection, not an instance)


What exactly is behaviour over here?

Is it that i can run the query as stand alone but cannot be used as part JPA API methods to fetch collections in a instance/entity?

Please let me know where iam went wrong
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic