I am incredibly excited by the fact that I have just written a single row to an embedded Derby database via the standalone JPA Hibernate implementation. Never before have I persisted an object via the power of just one Annotation. It totally rocks.
Of course what doesn’t rock is the million or so JARs that Hibernate uses to do it. I need to look at how much actually needs to be deployed in a minimal situation. JBoss seems to encourage the deployment of three uber JARs: the x-all.jars.
OpenJPA is lighter on the JARs but requires an agent to be running to, on the fly, byte convert the annotated POJOs into entity managed types. Interestingly both Hibernate and OpenJPA require javassist but seem to use it in different ways.
Currently all of the JPA implementations seem full of quirks and there is no obvious winner of convenience or completeness.
My first major problem is that Hibernate does not support Derby properly when it comes to autogenerating columns. It generates SQL that inserts null into the autogenerated column, I have been wondering whether that is the way that MySQL does it but it seems to be just plain wrong. It seems to be a slightly too literal relationship between the object and the underlying table that should be taken care of by the Dialect adaptor on the insert statement.
A search across the Hibernate forums results in the conclusion that the Hibernate team don’t like Derby and feel that people should be using HSQLDB instead. Aha! The Rails technique! I will answer the questions that I pose, not your lame questions.
I have no idea which of the embedded databases is better but I would think that since Derby is bundled with JDK 6.0 it might be an idea to see if your database solution supports it or not.
Anyway since I couldn’t get no Hibernate love I thought it would be a good opportunity to try swapping around JPA providers and see if the API was a swapable as promised. The logical candidate was OpenJPA as I presume that Apache pretty much eat their own dogfood.
The swap over was completely seamless from a coding point of view. All the annotations were unchanged and the persistence unit just needed the log in details changing as I am using the database in an embedded mode.
Everything else was bloody hard work though. My first mistake was that I had used some HQL queries in my initial stab at the work and these of course blew up. This was just my naivity and after checking the canonical EJB QL definition (the J2EE 5.0 tutorial seems to do the business) I got them working again.
However the most frustating issue was a bloody XML parsing error which gave a standard cvc error that was really unhelpful. The issue was about validating parsing. Although all the examples tend to give standalone XML documents OpenJPA needs the namespace data on the root element or it blows up real nasty.
This was a major blocker due to the obscurity of error and it should really be on a FAQ somewhere. Alternatively you can always specify the namespace of the XML schema and you should be fine no matter what implementation you are using.
Agent issues (usually relating to forgetting to add the agent parameter to the JVM arguments) accounted for the remaining difficulties but these issues are easier to spot. If you get a cast exception or a message that an object has no alias then it means that your annotated objects are not being read into the Entity Manager configuration because… the agent isn’t running.
Overall my experience with JPA has been very positive and it certainly makes using embedded databases a lot more appealing compared to say using JAXB and XML or simply property files. My experiences with the implementations is less than stellar though. Hibernate has a big plus in that it does not require the use of an agent but it uses a lot of JARs and some of them, like Log4J are not really necessary in a Java 5.0 world. I liked OpenJPA a lot, it still has a lot of JARs and like Glassfish/TopLink you still need to include a lot of bits and pieces from the App Server to make the thing work (Geronimo in this case not Glassfish) . I may stick with it for now but since I am using an agent based solution it might be worth checking out the RI Toplink Essentials.
There’s a lot still to do in the JPA SE area and I hope that one of the three contenders comes up with an unfussy single JAR solution soon because as an API JPA is excellent.