I struggled for ages trying to figure out how to do
lazy loading on a
one-to-one
relationship in hibernate. I’ll put you out of your misery now - you can’t!
I have one central table and 2
one-to-one
relationship tables hanging off it.
When the primary table object is created hibernate must do a select (or a join) on the other tables to determine if it needs to create a proxy for the
one-to-one
relationship or if it has to set the relationship object to null. Hibernate says that looking for the record in the database is the expensive part, so if it has gone to the trouble of finding it, it might as well use it.
My particular problem was that the 2 other records both contain lobs (Large OBjects), so it is not a simple case of loading a few columns. The general advice is to change the relationship to be
one-to-many
. This changes the code somewhat because it means you need to return a
List or a
Set.
Just as a bit of extra advice; think before you call size to determine whether you call
.size()
on the returned proxy to determine if there is an object to retrieve. Why? If you do, the proxy object will be hydrated to determine how many objects are in the set, thus destroying the point of the lazy loading in the first place.
The hibernate documentation suggests that this is all possible, there even appears to be options in the xml configuration file to switch on lazy loading for
one-to-one
relationships, but they have apparently no effect.
Don’t get me wrong, I like the hibernate technology; but when I checked the documentation it says “TODO” - thanks! Having wasted the last week trying to figure out why this was not working, trawling the web and reading countless blogs, articles and forums I eventually found a reference in the hibernate forum which was the most help and thought I would share it with you.
I have to say that for an area that is very often miss-understood, the documentation is severely lacking. As a developer writing documentation is the most boring part of our jobs, but ironically the most important.
Anyway the most useful article I found was in the hibernate forums:
http://forum.hibernate.org/viewtopic.php?p=2380205
I hit this problem in
October 2008 and my extensive research lead me to the above conclusion. If I have got it wrong then I am sorry and it proves my point about the documentation, but if I have got it right then it proves my point about the documentation ;)
If any one can shed some light on this please comment below.
“I’ll put you out of your misery now - you can’t!”
You can, use bytecode instrumentation and this:
@OneToOne( fetch = FetchType.LAZY ) @org.hibernate.annotations.LazyToOne ( org.hibernate.annotations.LazyToOneOption.NO_PROXY )
so it is possible but doesnt mean its a good thing…. /m