Why am I using Hibernate?
Something is going wrong in my life.
I read the book about Hibernate by its author, Gavin King, and I was really impressed, for the first time in my life, by an object-relational mapping system.
Although I doubted it would really save development time over writing SQL manually, I thought it wouldn't significantly increase development time either, and it had a few nice features (like being able to have a key-value Map in an object, and that Map getting persisted to its own table automatically).
But alas that was where my life started to go wrong. I've now completed a number of projects using Hibernate, and it's all been hell, really.
- I spent a whole work day trying to get the system to reconnect to the database after the connection was lost. (This is 1 line in WebTek, a Perl framework written by a friend, or in my hand-written Uboot code, etc.)
- If you use the Query API to say "give me any objects in the following set" and pass an empty set, rather than no objects getting returned, invalid SQL gets generated. I filed a bug report, but was told that generation of invalid SQL wasn't an error. (And he, the lead developer of Hibernate, was hardly polite, see the last comment.)
- If you persist a key-value Map to a database table (e.g. with a "key" col and a "value" col), if you overwrite a value in the Map (e.g. was "foo"->"bar" but now is "foo"->"baz") then you'll get a unique constraint violation as inserts of new values are done before deletes of old values. According to the bug report, this is expected behavior. My solution: drop the constraint, which I'm not too happy about. (Constraints are not only useful for data integrity, but also act as assertions which help database to choose the fastest statement execution plan)
I mean basically everything I try, no matter how simple, just doesn't work.
Hibernate has 150 KLOC (150,000 lines of code) and you still need an extra "connection pool software" (to solve the problem of reconnecting to the database, and also for performance reasons apparently). The recommended one seems to be C3P0 which is another 50 KLOC (and what a useless name!). You can imagine how many bugs such a piece of software must have, due to its size. I can only imagine all frameworks like e.g. "Gorm uses Spring uses Hibernate uses C3P0 uses database client uses database". Then your software has the union of the set of bugs which each layer contains – In addition to your own bugs.
Just now I've looked on a live server, which is under no load, and looking at the access log there were only been a few web requests at 9am, yet the web server log shows:
2009-06-02 01:53:41,889 DEBUG: com.mchange.v2.c3p0.impl.NewPooledConnection: com.mchange.v2.c3p0.impl.NewPooledConnection@bb21ab closed by a client. java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE at com.mchange.v2.c3p0.impl.NewPooledConnection.close (NewPooledConnection.java:491)
Nothing like "shouting" (all caps) in an Exception message to inspire confidence. Or using the word "debug" when throwing an Exception. Or for that matter throwing the baseclass Exception and not creating a specific Exception subclass.
Incidentally this 2009-06-02 log was written to the 2009-06-01 logfile, and there were no web requests at any point on 2009-06-01. (Not sure if Jetty or log4j is at fault there.)
I need to consider alternative technologies: basically anything I deploy with this stack just isn't going to work...