Hi,
I'm using Magma and finding out how transparent it can be. I'm trying Magma to see if the DDD principles can be applied to it. To retrieve, store and save aggegrate root objects a Repository object is used. A 'transient' Repository object is nothing more than a wrapper around an OrderedCollection, which contains store save and find methods. The client who is using this Repository object does not know which implementation is behind it. After retrieving the initial root aggegrate the client can manipulate the sub objects of the aggegrate root.
I managed to achieve Read Transparency. I specialised the Repository objects so they use a MagmaCollection instead of an ordinary OrderedCollection.
Use of a MagmaCollection vs. an OrderedCollection should be based on application requirements. Either type of collection works equally well whether transient or persistent. I recommend just picking the best one for the needs of that particular collection and sticking with it.
To do a Write Transparency, I added a decorator around the store / save methods of the Repository which automatically wraps the original Repository object in a session commit:[] block; enabling Magma to see the changes made to the 'saved' object and get them persisted. AddTransactionAroundMutators>>doesNotUnderstand: aMessage |result| (self isMutator: aMessage) ifTrue: [repositoriesController commit: [result := aMessage sendTo: decorated]] ifFalse: [result := aMessage sendTo: decorated]. ^result.
Hmm, to me, this is not worth the complexity. If you want your domain to be in control of the transactions (as opposed to the user), I suggest signaling MagmaSessionRequests. See http://wiki.squeak.org/squeak/5605 if you haven't already.
So I'm using a second MagmaSession to reload the object I'm about to commit and I'm noting to the first session to noteOldKeysFor: anObject usingHashingFromObject: theJustReloadedObjectFromTheSecondSession. Like this, the first session gets the hashes of the unmodified object in the repository, and the hashes get updated correctly automatically. It is a working solution (at least with my very limited testing), but I find it very complicated. Surely there must be a cleaner way to do an automatic hashkey update.
Wow, please do not do this approach, I agree it is way too complicated and definitely not the right way to use Magma.
Please use MagmaSessionRequest (signalNoteOldKeysFor:, et al) and handle it in whatever app-level controller you're using. It is benign if it isn't handled, so transient applications will work transparently.
Other things I already tried is to enable WriteBarrier, but could not get that working.
WriteBarrier is a separate package which I don't believe works on Pharo. I do not maintain this package.
Can anyone help me on this one? I'm finding it a bit strange that Magma can correctly save my changes, but not determine if a hash key update is necessary.
Detecting key changes automatically was impossible without slowing down commits; the
MagmaSessionRequest signalNoteOldKeysFor: myAttribute
is so easy to just put into the appropriate setter, so it wasn't a good trade-off to compromise performance for this minor increase in transparency.
Regards, Chris