My journey through the land of Java Persistence API implementations continues. Originally, I used TopLink, because that’s what came with Glassfish, and someone told me I should use Glassfish and I believed them.
However, TopLink’s error messages run the full gamut from useless to confusing to misleading. For example, if an Entity class is a subclass of a class defined in a jar that’s not in the same war, you get a ClassNotFoundException that doesn’t tell you what class it was looking for, what class it was trying to load, or anything else of use, really. This is only one example, debugging toplink errors is all about screwing around until it starts working again.
Then I tried OpenJPA, as mentioned in my previous post. Unfortunately, OpenJPA doesn’t support all the features I’m using, like a collection that’s a Map where the key is an Entity class and a field in the target object. Or something – I didn’t delve far enough into this to figure it out, but changing that to a list and doing my own linear search seemed to fix THAT issue, but it was only the first thing that OpenJPA choked on. OpenJPA’s error messages were much better than TopLink’s, but it was lacking in features.
Now I’m trying Hibernate. However, hibernate wouldn’t let me put FetchType.EAGER onto collections inside my entities. Apparently for the Hibernate folks, FetchType.EAGER means it must be done in the same SELECT query, so fetching multiple collections returns a number of rows equaling the product of the number of rows in all those collections. I guess they forgot that you can actually do multiple queries in rapid succession and then pick up the results seperately. That would be too user-friendly for a JPA implementation, and violate the secret code of JPA implementors (that secret code being: if you haven’t worked on the source code for our implementation for at least a month, screw you!). Hibernate certainly doesn’t earn a gold star in error reporting – for the getters lacking annotations it just gave me a column name (no class name) so I had to go searching around since many of my classes have same-named columns. For the FetchType.EAGER problem, it didn’t give me a class name, column name, or even a suggested solution! Luckily google indexes their forums and I did manage to sort these issues out with a bunch of searching online and in the source code.
So …. the question mark remains on the end of the subject because I can’t really say whether Hibernate is going to be an improvement over TopLink Essentials and OpenJPA or not. Maybe after this I’ll be qualified to launch some kind of “Best of the worst: a JPA implementation comparison” website where I can compare JPA implementations for people’s benefit. Or maybe I have better things to do …