I finally had the chance to use Hibernate on a recent project. Hibernate is a full-featured and popular API, but it has some problems. Here are my grievances.
Step away from the thesaurus
I feel like it was designed by pompous thesaurus-loving assholes. If you want to query a table and bring back just one column, what do you do? Oh, well that's simple. Add a Projection. Huh? I never would have guessed that. By coming up with crazy names for simple operations, the creators of Hibernate have taken away something very important. Developers new to Hibernate can't discover and learn it by doing (coding). The API is not in touch with reality. Let's go to the javadoc for the Projection interface:
"An object-oriented representation of a query result set projection in a Criteria query. Built-in projection types are provided by the Projections factory class. This interface might be implemented by application classes that define custom projections."
Good job Gavin King. Use the word you are defining in the definition. If I didn't have someone helping me with Hibernate, it would have taken me hours to discover this feature.
Reflection is cool...sometimes
A major selling point for Hibernate is that you don't have to change your object hierarchy in order to get persistable objects. What the hell does that mean? Usually ORM's require the user to subclass some PersistableObject in order for the object to be persistable. This is usually too restrictive for mature code-bases. With Hibernate, any POJO can be persistable. How do they that? -- Reflection my friend.
Reflection is cool until you need to do some debugging. Let's say a private instance variable is being set, and you want to know who/what is setting it. OK, put a breakpoint on the setter for the instance variable in question and see what happens. When Hibernate changes the value, you'll see nothing. Hibernate stealthily sets the value using reflection and the debugger is clueless. OK, put a watch on the instance variable. That will do the trick, right? Wrong. The same thing happens, Hibernate changes the variable and the debugger has no idea the value changed.
Lazy initialization error
This is infuriating for the first-time user. Hibernate only fetches things when it absolutely needs to. By default it's...well...lazy.
For example (pseudo code):
get session fetch someObject from the session close session someObject.getAValue() ---> Boom! Lazy Initialization Exception
There are three fixes to this problem:
- Leave the session open while you are accessing the object values.
- Configure Hibernate to not use lazy initialization.
- Stop using Hibernate. :)
There are more things that bug me about Hibernate, but I'm tired of typing and I'm sure you're tired of reading. Is anyone still reading?
I beleive you can force loading of object reference at a property level.
ReplyDeleteYeah. That's option #2.
ReplyDeleteI find your perspicacity regarding projections to be of a dubious nature. The utilization of the word "projection" is a clear endeavor to eschew obfuscation on the part of the Hibernate architects. Indubitably, this blog lacks the acumen for purposive erudition.
ReplyDeleteoh , i thought 2 meant setting it globally
ReplyDeleteI have one thing to say: Long live the DMF
ReplyDeleteHibernate does a nice job of mapping a ResultSet to a data object. It'll save that boilerplate code for each persistable object.
ReplyDeleteBut that's all it does well. Its reference handling is a joke. To avoid LazyInitializationExceptions, I've seen code where after the DB retrieval, there are a bunch of getters called on the object. Or, you have to write clone() methods, so that your persistable objects, once retrieved, are copied to other objects (Hibernate allows circular references...ever try to write a clone() method for objects with circular references?)
The developer cannot specify the depth of the fetch on each call, which would go a long way toward solving this problem. But Hibernate doesn't give the developer this kind of control. So your only option is to break your Hibernate references, and retrieve one table at a time as you need it.
So what you are left with, in the end, is an extra layer of complexity and possible failure, and all it does for you is save you ten minutes of coding per persistable object. As soon as you encounter your first HibernateException, that ten minutes is spent many times over.
Deppen has it right: the DMF kicks Hibernate's ass!
We should open source the DMF. I'm sure Chase wouldn't have a problem with that.
ReplyDeleteOf course, then we'd have to field questions like "WTF. Why the hell did you call it 'Lorax'?"
[...] I had another run-in with Hibernate the other day. I was working with a very simply database model. [...]
ReplyDelete