So, having defined at least some of out terms, how can we map this reasonably.
I'm speculating, because I haven't actually coded this, but here's what I'm thinking. Warning: this starts getting into deeply technical GLORP internals.
Assume a DictionaryMapping, which holds onto two sub-mappings, one for the key and one for the value. This dictionary mapping is going to build objects of some kind of special association type, call it GlorpAssociation. This holds onto a key, a value, and an owner, but it's not going to have a normal kind of descriptor, because it'll be reused in lots of different contexts. The dictionary mapping might or might not also need to know what the table is. It might just be implied by the sub-mappings.
So to read one of these, either directly, or as a join, we'd need to gather up all the fields needed for both the key and the value (and possibly the owner id) and we'd need to add in the join criteria, if any, needed for both if they're foreign keys, plus the join criteria to the association table. I guess that means the dictionary mapping would need to know it, since it doesn't seem like the sub-mappings would.
For writing, recall that GLORP assumes that each row is uniquely owned by a particular object. This is because GLORP builds up a "row map" of rows, indexed by their owner. However, one notable exception is the link table used for a many-to-many relationship. There's no unique owner for those. So what GLORP does is create an object, called a RowMapKey, whose sole job is to own these intermediate rows. Basically, a RowMapKey holds two objects (or more, but let's ignore that for now), computes its hash based on their hashes, and compares equality by comparing both of those for identity (regardless of their order within the RowMapKey).
This is going to be similar. The association objects we're creating won't have a primary key, so we can't really cache them. That means (or at least suggests) that we can't rely on their identity, and if we can't do that, we can't use them as keys in the row map. So we'll probably need to create RowMapKeys for the key/value/owner trio, or else we'll have to allow these GlorpAssociation objects to act in the same sort of way that RowMapKeys do (which could be tricky, because there's some internal ugliness to make that work, see e.g. the RowMap method isRowMapKey:, which does x class == tests).
Then there's the question of API's. Are there useful things you can do to query across a mapped dictionary? e.g. anyKeySatisfy:? Presumably, like an in-memory dictionary, anySatisfy: should operate on the values.
The other API question is how to write the descriptors for this. Can we have a sufficiently nice model that all 9 of these cases can be expressed gracefully. I'm not sure. Separating out into key and value sub-mappings seems to handle a lot of the issues, but there may be others lurking.
So, lots of questions. Not so many answers yet.