10.15.07

Can’t write SQL? Try Hibernate

Posted in Coding at 8:30 am by David Kellogg

The crazy thing about Hibernate is that it replaces the easiest part of the database, SQL. Hibernate sounds impressive, with its Spring framework and ease of use, but something is missing. It’s scalability.

hindenburg

Hibernate was never designed to scale. It was designed to be easy. What it does not do is federate databases, remap to new machines, migrate data and help you optimize your database. It falls into the usual Java mistake of first, placing all visible components in the programming language as Objects, then preventing you from using the best features of various databases. It corrupts MVC by placing the model in the controller and makes it more difficult to scale the databases separately.

What happens when you need to add a second database on a separate IP? A second session factory is necessary, which is essentially a second connection. If you try a single find on multiple databases, good luck. I read that multiple databases can be managed by a program called Castle, which is .Net only. I know there are other projects (like shards), but these will only be opaque solutions on top of Hibernate. Multiple databases make cross-db joins almost worthless. At that point, you lose the joy of Hibernate.

And what is the joy of Hibernate? Let me explain my travails.

Day 1:

I downloaded hibernate3.jar and its brethren. I launched quickly into the tutorial. The tutorial said it will take 3 days to jump fully into Hibernate. I thought, “That’s stupid. I can do this in a couple of hours.”

Day 3:

I finally finished my tutorial. And that was just the tutorial. It took quite a while to find all of the jars. The tutorial had errors. It claimed I could use “native” for the autoincremented column. I had to use “increment” instead. In the old days, a simple, useless SQL error would complain about your syntax. A quick trip to the MySQL docs solved this issue. With Hibernate, there is almost no way to debug it, because instead of a command line, you receive a stack trace for every little issue. I’m sure stack traces are loved by many Java fanboys, but really, won’t SYNTAX ERROR do?

After trying out the completely useless Java DB server, which never saved my persistent data, I switched easily to MySQL server. I hunted for my data. And hunted. In MySQL, my EVENTS table ended up in the worst possible database, “mysql”. Hibernate shows no respect! The mysql DB is for system information, not your stupid data. This is not good.

mysql> show tables;
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| EVENTS                    |
| columns_priv              |
| db                        |

Now here’s the killer issue. When my company grows, and I need 5 or 50 clusters, will Hibernate help me? No. A separate connection factory is necessary for each database, and each IP. All of the ease of use goes away when I add a second IP.

What does Hibernate replace?

SELECT * from events where name=’David Kellogg’

I could have written that in my sleep. Adding a column is not hard. SQL makes that easy. Mapping and casting in your code is not hard. What is so hard that it requires Hibernate? Not much really.

The real issue is that Hibernate is a framework. A framework is like a Minnesota bridge. When one beam collapses, the whole bridge falls down. Once you change one item beyond what the framework allows, the framework becomes brittle, and collapses under the weight of ease of use.

6 Comments »

  1. Michael said,

    October 26, 2007 at 7:42 pm

    Wow Dave, you really show a lot of ignorance on this topic. I’m sure there are things that you have a lot of expertise on, but this is clearly not one of them. I thought about just listing all the things you are wrong on, but you’re really not right about anything. Hibernate scales to federated databases just fine, you can use native SQL very easily for optimized, database specific SQL, a session factory is not a connection to a database, the SQL you showed was not generated by Hibernate, the reason you got the ‘mysql’ db is because that’s the db you told Hibernate to use (guess what you get by default if you don’t specify what db), Hibernate does not have “connection factories”, you can test Hibernate queries (HQL) interactively against a db (there’s a plugin for Eclipse to make this easy), … the list goes on.

    Maybe there were some mistakes on the tutorial you read and/or with the documentation, who knows. You clearly have opinions on Java and frameworks, which makes one wonder why you spent three days doing a Hibernate tutorial. But seriously, in the words of Public Enemy : “Get your shit correct.”

  2. David Kellogg said,

    October 29, 2007 at 10:26 am

    No. You’re wrong on every point.

    Session session = sessionFactory.openSession();

    This pulls a connection from the connection pool. If that pool contains multiple database, it is pretty much useless, since the joins will be fairly slow. You need a new pool for each database. Furthermore, you need a different session factory for each IP. Here’s the config for this.

    hibernate.connection.url = jdbc: postgresql://localhost/mydatabase

    That’s not an array. It’s just one IP. It’s just one database.

    I don’t care about optimization. I care about scalability. That’s where Hibernate fails. This is the problem with Ruby on Rails and Active Record. Hibernate suffers from the same myopia.

    The tutorial reflects on the haphazard way that Hibernate works. Hibernate is not well thought out. It’s a database abstraction layer that should have been written differently. Once you get sucked into Hibernate, you cannot do the same for your Python or Perl code that also must connect to the same database. You are in a Java-only HQL world. In the end, it just replaces “select * from events”. That’s not impressive to me.

    I repeat.
    1. It does not scale
    2. It does not port
    3. The tutorial is broken
    4. It has an inflexible connection factory
    5. It places tables in mysql by default

  3. Michael said,

    November 6, 2007 at 2:37 pm

    Your points are just as wrong as invalid as in your original post

    1. It does not scale — Not true. This is obviously your favorite card. If you want to scale Hibernate horizontally, then use its subproject Hibernate Shards. It lets you plugin your own horizontal scaling strategy, or you use some “standard” ones. It is a rather proven technology, since it was developed by a certain search company that operates on a pretty huge scale.

    2. It does not port — Not true. I’ve personally taken a Hibernate app built on MySQL, tweaked the configuration file, and re-deployed it to Oracle.

    3. The tutorial is broken — Ok, I’ll take your word on this one. There are numerous Hibernate tutorials available as well as books on it because it is used so much. A search for “hibernate tutorial” produces 2.2M results on Yahoo Search.

    4. It has an inflexible connection factory — This is a reiteration of #1. If you need multi-db support, then use Shards. You can supply your own connection strategy to it, making it as flexible as you need it to be.

    5. It places tables in mysql by default — Not true. It places tables in whatever database you tell it to. If you default to the mysql db, then that’s what it will use. You are trying to blame Hibernate for your own mistakes. It’s not magic: garbage in, garbage out.

  4. David Kellogg said,

    November 6, 2007 at 8:54 pm

    I set myself up to win, here. I knew someone would say, “look project X (shards, Castle, whatever) is the extra umph you need to rock your DB.” You’re right, but I said Hibernate itself was not designed to scale, because that’s what this article was about.

    Yes Java MySQL code ports to Java Oracle code, but so what? It’s still stuck in Java land. No one suggested there is a Perl module for this (not on CPAN). Does it work with Bash or COBAL (yes COBAL does work with MySQL)? Let’s run down some common language recommendations.

    Database: Java
    Mathematics: Java
    Web front end: Java

    I see a trend here. Porting means it stays in Java. No Hibernate does not port outside the Holodeck of Java.

    In my DB, I found some stupid Hibernate coder stuck data in the “mysql” database. I don’t find this professional. It sounds kinda broken.

    Not every Hibernate tutorial is perfect I guess, but the freaking hibernate.org tutorial should get it right. http://www.hibernate.org/hib_docs/v3/reference/en/html/tutorial.html
    is broken.

    Scaling horizontally requires you to know your data and how it connects to itself. You as a programmer need to be very flexible. But then was the last time you found a flexible framework? Frameworks are designed not to bend. In the end, I might as well write my federation software myself. The stupid thing is, Shards lets you write custom federated calls. Then can’t you just write them yourself in the first place?

  5. Alpha Omega said,

    January 17, 2008 at 11:38 am

    David you are truly a lost cause. Obviously no matter what is said here, you will always be “right”, right? (Sly grin) The truth is your lack of expertise with Hibernate (and Java too) is the cause of your troubles. Just stick with .NET and let the big boys use the big boy toys.

  6. David Kellogg said,

    September 3, 2008 at 11:25 pm

    Alpha,
    I love how some people think, in terms of one lousy framework (Hibernation) vs. another (.NET). I’m not a fan of either, because it locks you into a solution. If that solution does not meet your needs, well good luck changing the source. Just for the record, it is possible to segment/shard your database without resorting to yet another framework. Frameworks are great for novices.

Leave a Comment