hibernate/hibernate-ogm — pull request #304 by gunnarmorling (2014-03-07 17:48:31+00:00)
Title: 30%-Review - OGM-469 ("Fetch embedded associations when getting the hosting tuple in MongoDB")

Hi,

This PR is for getting early feedback on the general direction of OGM-469, so please no comments about JavaDoc and the like :) This is based on my earlier PR for OGM-428, you can find the actual diff at https://github.com/gunnarmorling/hibernate-ogm/compare/gunnarmorling:OGM-428...OGM-469.

The first four commits are preparational work and beneficial either way. They basically move "associationKind" and "collectionRole" from `AssociationKey` to `AssociationKeyMetadata` as these don't differ between keys of the same assocation. This may allow to cache this information at some later point to avoid repeated calculation. Also `GridDialect#isAssocationStoredInEntityStructure()` expects `AKM` instead of `AK` now, as this decision shouldn't depend on a specific instance of one and the same association.

The actual change is in the last three commits. It establishes a notion of session-scoped storage. For now it's using a `ThreadLocal` bound to the `OgmSession` lifecycle. This did the trick, but apparently that's not the way it should be and we need help from the ORM team to do it properly (I'll ask them for support; I saw there is the notion of an "owner" in `SessionImpl`; this seems promising as it already is populated with the wrapping `OgmSession` instance, we just can't access it as there is not getter).

This session-level store backs a `SessionContext` which is exposed to grid dialect ops and allows a dialect to store information between requests of one session. Also `TupleContext` has been enriched with information about associations embedded within a tuple to load. `MongoDBDialect` uses this to add the association fields to the loaded projection, thus fetching embedded assocations in the load storing the embedding document in the session context. `getAssocation()` preferably gets the assocation from the cached embedding entity document. This gets rid of one roundtrip to the store (see `ReadPreferencePropagationTest` which is a nice vehicle to do assertions on the actual datastore ops issued by the MongoDB dialect).

But the price for this seems quite high as it increases complexity of dialects; in particular each dialect itself has to manage the session-level cache in this approach. I'm thus wondering whether/how we could move more responsibility to the engine itself. I only have a vague idea for this atm. but I wanted to share my current findings with you to get your insights and hopefully we'll be able to find a satisfying solution. Who managed to read up to here will be sponsored a drink at our next physical meeting. Thanks :)