I have solved this now a number of different ways and thought I'd ask the community for your take on this.
Parties can have many PostalAddresses, indexed by type, in my domain interfaces. So you can say:
PostalAddress address = someDude.getPostalAddress(preferred);
address = someDude.getPostalAddress(mailing);
and so on.
At the database level, without even thinking of JPA, I would do something like this:
party <--- joinTable --> postalAddress
...where the join table would have effectively three columns (partyID, postalAddressID, and type). The intent is that a party may have many postal addresses indexed by type, but also that in some situations a postal address might be shared between two parties. This implies that the type rides with the association, not the address.
When you translate this to JPA, you run into some problems. Or at least [i]I[/i] run into some problems. :-)
First, while it is true that logically the relationship between parties and postalAddresses is many-to-many, the relationship has some extra state on it, namely the type.
So my first conclusion is that the @ManyToMany annotation won't work, because it simply generates a two-column join table (no room for the type). First question: this isn't erroneous, is it?
Assuming I'm still on solid ground, that means that I need to define an entity for the join table. No problem; I've done this before. Let's call it a PartyPostalAddressBinding. So far so good. This entity never shows up in the domain layer; it exists only as a by-product of JPA usage.
My next problem is that I would like it to have a primary key that (obviously, I hope) consists of the type and the partyID. So, my second question: how do I define my PartyPostalAddressBinding to have a compound primary key whose component parts are themselves JPA relationships (ManyToOne for each side--many PartyPostalAddressBindings may have one Party, and many PartyPostalAddressBindings may have one PostalAddress)? It appears that IdClass won't work here, but I may be wrong about that.
(If I have to give up on that and simply use a (redundant) serial primary key via an @Id annotation, that is not a huge deal; I'll just make sure that there's an appropriate unique constraint on partyID and type.)
Lastly, am I correct in saying that no usage of MapKey will get me what I want here? Or rather that the only way a MapKey annotation would help is if I could somehow solve the compound primary key problem, and could pass an instance of either my @IdClass or...or...my @EmbeddedClass? as the key?
Finally, if that's all true, then it seems to me I have no choice but to say that a PartyEntity has a @OneToMany relationship with PartyPostalAddressBinding, and that I will need to roll my own map access. Is that correct?
Thanks,
Laird
[Message sent by forum member 'ljnelson' (ljnelson)]
http://forums.java.net/jive/thread.jspa?messageID=215387