Justin
Justin

Reputation: 584

Nhibernate, Domain Model, Changes, Disconnected, Cloned (Need better title - but can't express it clearly!)

Sorry about the title - hopefully the question will make clear what I want to know, then maybe someone can suggest a better title and I'll edit it!

We have a domain model. Part of this model is a collection of "Assets" that the user currently has. The user can then create "Actions" that are possible future changes to the state of these "Assets". At present, these actions have an "Apply" method and a reference to their associated "Asset". This "Apply" method makes a modification to the "Asset" and returns it.

At various points in the code, we need to pull back a list of assets with any future dated actions applied. However, we often need to do this within the scope of an NHibernate transaction and therefore when the transaction is committed the changes to the "Asset" will be saved as well - but we don't want them to be.

We've been through various ways of doing this

Obviously these each have various (massive!) downsides.

Any ideas? Let me know if this question requires further explanation and what on earth I should change the title to!

Upvotes: 1

Views: 397

Answers (4)

asgerhallas
asgerhallas

Reputation: 17724

I have been working around a similar problem where performance was also an issue, thus it was not possible to re-load the aggregate using a secondary (perhaps stateless) session. And because the entities that needed to be changed "temporarily" where very complex, I could not easily clone them.

What I ended up with was "manually" rolling back the changes to what would be the assets in your case. It turned out to work well. We stored each action applied to the entity as a list of events (in memory that is). After use the events could be re-read and each change could be rolled back by a counter-action.

If it's only a small variety of actions that can be applied, I would say it's easily manageable to create a counter-action for each, or else it might be possible to create a more generic mechanism.

We had only four actions, so we went for the manual edition.

Upvotes: 1

James Kovacs
James Kovacs

Reputation: 11661

You could manage this with NHibernate using ISession.Evict(obj) or similar techniques, but honestly it sounds like you're missing a domain concept. I would model this as:

var asset = FetchAsset();
var proposedAsset = asset.ApplyActionsToClone();

The proposedAsset would be a clone of the original asset with the actions applied to it. This cloned object would be disconnected from NHibernate and therefore not persisted when the Unit of Work commits. If applying the actions is expensive, you could even do the following:

asset.ApplyProposedChanges(proposedAsset);

Upvotes: 1

Neil Moss
Neil Moss

Reputation: 6838

It's been a while since I had any NHibernate fun, but could you retrieve the Assets using a second NHibernate session? Changes made to the Asset will then not be saved when the transaction on the first session commits.

Upvotes: 1

SwDevMan81
SwDevMan81

Reputation: 49988

Sounds like you want to use a Unit of Work wrapper, so you can commit or revert changes as needed.

Upvotes: 0

Related Questions