Java

Ooo JPA, JPA

I normally have nothing good to say about ORM so I had a pleasant surprise today when I was able to generate four One to Many object relationships in about four or five hours.

I’m currently using TopLink although I try to stick to space inside the standard and avoid getting dragged into vendor extensions. I actually prefer OpenJPA from a testing point of view as TopLink won’t seem to play ball unless there is a persistence.xml in a directory called META-INF at the root of your classpath.

The basic syntax is pretty simple, you create a field that is a Collection of the Entity that represents the other side of the relationship, I used a List but then wondered why I had done that. You then annotate that field with @OneToMany and then specify the Join mechanism. Now this is where it usually gets messy and I have to say there is a certain amount of gnarl to this one. I had a relatively simple Join Table on the go but thankfully the annotation @JoinTable needs to know only three things.

Firstly the name of the table (as per the @Column annotation) and then the JoinColumns and InverseJoinColumns parameters. These names are correct but probably seem fiercer than they need to be. Both parameters take an array of @JoinColumn annotations (nested annotations! a first for me). Even if you just have one, wrap it in curly braces. The @JoinColumn syntax is the same as that for @OneToOne and specifies which column to resolve the @Id lookup with.

Join Columns identify the Id of the entity that has the Collection field; this class in other words. The InverseJoinColumns identify the Ids of the other entities that exist in the relationship.

So if Foo has a Collection of Bars then JoinColumns identifies the database columns that contain the Ids of Foo and the InverseJoinColumns identify the Ids of the Bars.

To be honest TopLink has decent enough logging that you can usually muddle along coredumping the SQL that the annotations are building up. My worst mistake was mixing up the @Table annotation with that that of @JoinTable and trying to select from my join table joined with, my join table.

The nice thing is that I was able to very quickly build up four foreign key relationships, all using join tables (some of which had been badly denormalised) and all by annotating the POJOs that also serve a domain purpose. I had to add some Setters for testing purposes but apart from that if I wasn’t using the data in the application I didn’t have to describe it in the configuration.

Good work JPA!

Standard
Java

Observe the Madness!

I decided to give OpenJPA another go now it’s all incubated and promises that running agents are the way of the past. Before I can really try any of that though I have a huge problem with my persistence.xml file not being parsed. I had this problem last time I tried OpenJPA and it took me ages to solve then as well.

I ended up looking at my own blog for any clues as to how I fixed it; I was infinitely recursing up my own arse. Anyway to help improve my Googling for a solution in future… If you are using OpenJPA and you get the following error:

cvc-elt.1: Cannot find the declaration of element 'persistence'.

Then replace the first persistence tag in the following way:


Not <persistence> but
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

This simply defines what the Schema should be for the persistence unit. To understand why you’re doing this see this post. Note that the post is titled Dumb User Question but it’s really not, if you look at the example persistence file given in the documentation you would forgive anyone for making this mistake.

Standard