Interesting question, and the answer is; yes, I have though about it very well, and my conclusion is still that there are soo many similar features in (n)Hibernate to what I want, that with a little bit of help from an insider with more "architectural knowledge of (n)Hibernate", this feature should be small in code. "small" when you know the inside of the product...
On May 4, 8:18 pm, Carlos cubas <[email protected]> wrote: > tz, have you considered that, maybe just maybe, you are swimming in the wrong > direction? by yourself? > > -Carlos > > Practice makes perfect, but if no one is perfect, why practice? > > > > > Date: Tue, 4 May 2010 11:49:35 -0700 > > Subject: [nhusers] Re: Refresh from second level cache > > From: [email protected] > > To: [email protected] > > > "Revert changes with the state of my first load" is what the user > > thinks when she has changed an entity, but regrets. Thus wants to > > cancel. However, she doesn't want to be punished by another database > > hit. I'm sure many other people decide in this case to start a new > > session or evict the object graph and get it again. All to me sound > > like a half-baked solution for reasons I've mentioned before. Another > > half-baked solution is to say that you only change the entities once > > you're 100% sure (no, I want to "commit" once I'm 100% sure). > > > Having said all this, what I want to reach here, completely fits in > > how I want my application to work. I think it is compatible with UoW > > and all those other fancy design patterns. This is clearly a missing > > feature to me. Therefore, I was really hoping for a technical > > satisfying answer, rather than advocating that I'm doing is something > > which is not written in one of the tutorials. > > > So, please... does anyone know how I could do this trick of reverting > > changes in a graph? > > > On May 4, 7:32 pm, Fabio Maulo <[email protected]> wrote: > > > There is something saying me that your problem is in another place. > > > "Revert changes with the state of my first load"..... mmmmm > > > > On Tue, May 4, 2010 at 3:05 PM, tz > > > <[email protected]>wrote: > > > > > Thanks for confirming that. I silently started guessing that the > > > > Refresh method shouldn't be what I should use. I started writing my > > > > own "RevertChanges" on a graph, but I'm stuck on how to evict > > > > collections (plus the attached pending deletes/adds). See my code > > > > below: > > > > > public static class ISessionExtensions > > > > { > > > > public static void RevertChanges(this ISession session, object > > > > obj) > > > > { > > > > var source = session as IEventSource; > > > > var action = new RevertChangesCascadingAction(); > > > > > action.RevertChanges(source, obj); > > > > } > > > > > private class RevertChangesCascadingAction : CascadingAction > > > > { > > > > public override void Cascade(IEventSource session, object > > > > child, string entityName, object anything, bool > > > > isCascadeDeleteEnabled) > > > > { > > > > DoRevert(session, child); > > > > } > > > > public override IEnumerable > > > > GetCascadableChildrenIterator(IEventSource session, CollectionType > > > > collectionType, object collection) > > > > { > > > > var coll = collection as > > > > NHibernate.Collection.IPersistentCollection; > > > > var collectionEntry = > > > > session.PersistenceContext.GetCollectionEntry(coll); > > > > > // TODO: HELP!!! > > > > //session.Evict(collection); > > > > //collectionEntry.LoadedPersister.Recreate(coll, > > > > collectionEntry.LoadedKey, session); > > > > > // evicts don't cascade to uninitialized collections > > > > return GetLoadedElementsIterator(session, > > > > collectionType, collection); > > > > } > > > > public override bool DeleteOrphans > > > > { > > > > get { return false; } > > > > } > > > > public override bool PerformOnLazyProperty > > > > { > > > > get { return false; } > > > > } > > > > > protected void DoRevert(IEventSource session, object obj) > > > > { > > > > EntityEntry entityEntry = GetEntityEntry(session, > > > > obj); > > > > > IEntityPersister persister = entityEntry.Persister; > > > > EntityMode mode = persister.GuessEntityMode(obj) ?? > > > > EntityMode.Poco; > > > > persister.SetPropertyValues(obj, > > > > entityEntry.LoadedState, mode); > > > > } > > > > > protected EntityEntry GetEntityEntry(IEventSource session, > > > > object obj) > > > > { > > > > IPersistenceContext context = > > > > session.PersistenceContext; > > > > > if (obj is ValueType) > > > > return null; > > > > > if (context.IsEntryFor(obj) == false) > > > > return null; > > > > > EntityEntry entityEntry = context.GetEntry(obj); > > > > return entityEntry; > > > > } > > > > > public void RevertChanges(IEventSource session, object > > > > obj) > > > > { > > > > EntityEntry entityEntry = GetEntityEntry(session, > > > > obj); > > > > > DoRevert(session, obj); > > > > > session.PersistenceContext.IncrementCascadeLevel(); > > > > try > > > > { > > > > new Cascade(this, CascadePoint.AfterUpdate, > > > > session).CascadeOn(entityEntry.Persister, obj); > > > > } > > > > finally > > > > { > > > > > session.PersistenceContext.DecrementCascadeLevel(); > > > > } > > > > } > > > > } > > > > } > > > > > On Apr 30, 7:55 pm, Jason Dentler <[email protected]> wrote: > > > > > Confirmed it with Fabio: "Refresh is an explicit hit to DB" > > > > > > On Fri, Apr 30, 2010 at 8:35 AM, tz < > > > > [email protected]>wrote: > > > > > > > * Transaction over a read didn't help (see reply on Jason Dentler) > > > > > > * Second level cache is for sharing data across transactions > > > > > > > On Apr 30, 12:24 pm, John Davidson <[email protected]> wrote: > > > > > > > It does not matter what the UoW pattern says about data read. You > > > > > > _REALLY_ > > > > > > > need to put a read action in a NHibernate transaction if you want > > > > > > > to > > > > > > improve > > > > > > > performance. Not having your reads in a transaction may be why you > > > > need a > > > > > > > second level cache (to compensate for not following the specified > > > > rules). > > > > > > > Most of the transactional databases now wrap a read action in an > > > > > > > ACID > > > > > > > transaction on their own, if the request is not already in a > > > > transaction > > > > > > - > > > > > > > this activity by the database takes more time and resource than > > > > > > > if it > > > > is > > > > > > > done in the application with NHibernate and UoW. > > > > > > > > John Davidson > > > > > > > > On Fri, Apr 30, 2010 at 7:14 AM, tz < > > > > > > [email protected]>wrote: > > > > > > > > > Thanks for the reply. See my comments inline > > > > > > > > > On Apr 29, 8:26 pm, Jason Meckley <[email protected]> > > > > > > > > wrote: > > > > > > > > > I would approach the problem in a completely different manner. > > > > > > > > > 1. no long running sessions > > > > > > > > > 2. only use 2nd level cache in edge cases as a last resort > > > > > > > > > 3. for multi-step operations/commands I would use an > > > > > > > > > intermediate > > > > DTO > > > > > > > > > to store updates. When the user clicks "save" is when i would > > > > alter > > > > > > > > > the domain objects. this makes undoing changes much easier. > > > > simply > > > > > > > > > abandon the DTO. > > > > > > > > > I'm not sure whether you do understand my question, but I can't > > > > relate > > > > > > > > any of your reply to my question. I also don't agree with what > > > > you're > > > > > > > > saying... > > > > > > > > * I don't know what "no long running sessions" would solve for > > > > > > > > my > > > > > > > > issue. All these things you're proposing are a "very complex" > > > > > > > > way > > > > to > > > > > > > > do Evict/Load on the same session. > > > > > > > > * 2nd level cache is for performance reasons. The issue I'm > > > > > > > > posting > > > > > > > > about is also for performance reasons. So, this cache stays > > > > > > > > * Why would I do any object dirty management myself, if > > > > > > > > nHibernate > > > > can > > > > > > > > do it for me. > > > > > > > > > > if you do continue down this path are all your session calls > > > > > > happening > > > > > > > > > within a transaction? Proper use of NH dictates that all > > > > operations, > > > > > > > > > both read and write, should happen within at transaction. > > > > > > > > > This is > > > > > > > > > critical for client POIDs, proper UOW management and 2nd level > > > > cache. > > > > > > > > > Again, no answer on my question. Even more, I don't agree with > > > > you... > > > > > > > > * UoW pattern doesn't say that a read should be in a ACID > > > > transaction. > > > > > > > > UoW itself is a "business transaction" implementation, which is > > > > based > > > > > > > > optimistic concurrency ideologies (meaning that you shouldn't > > > > > > > > keep > > > > an > > > > > > > > ACID transaction open between the reads and the writes). > > > > > > > > > What I want is simply a Update() which does what Evict/Load > > > > > > > > does, > > > > but > > > > > > > > not with giving me a new instance. That's all I'd want to know. > > > > > > > > I > > > > know > > > > > > > > nH keeps the original state in the session (and the second level > > > > > > > > cache), so it shouldn't be that difficult I assume. > > > > > > > > > > On Apr 29, 2:05 pm, tz <[email protected]> > > > > wrote: > > > > > > > > > > > Hi guys, > > > > > > > > > > > I'm working with a long running session which contains all > > > > > > > > > > my > > > > > > required > > > > > > > > > > data. Further, I use level 2 cache intensively, to cache > > > > > > > > > > that > > > > > > > > > > information. I let my user edit this data directly using UI > > > > > > controls. > > > > > > > > > > > The user can decide to cancel the modifications, which I > > > > > > > > > > though > > > > I'd > > ... > > read more »- Hide quoted text - > > - Show quoted text - -- You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
