This is a nice solution. This is what I was missing - I couldn't quite figure out if I could intercept when Ibatis is setting a property. Very impressive, thank you! Based on the response I have received for my question on this list, I'd say the Ibatis.Net community is very much alive! That, or everyone has dealt with the pain of dirty tracking ;)
________________________________ > Date: Sat, 30 May 2009 00:44:54 +0800 > Subject: Re: Dirty Tracking Issue > From: [email protected] > To: [email protected] > > sorry I attached the wrong mapping file :-( > > > On Sat, May 30, 2009 at 12:29 AM, Yaojian> wrote: > > Yes, the constructor is better in simplicity, and is slightly better in > performance if it is public :-) > > If you wanna to use the constructor solution, note that all auto-properties > must be replaced by a normal property with a backend field. for example: > > > > public String Name { get; set; } > > must be replaces with a normal property like: > > private String m_Name; > > public String Name { get { return m_Name;} set { m_Name = value;}} > > > and the constructor should set the value to the "m_Name" field instead of the > property. > > > > > On Sat, May 30, 2009 at 12:21 AM, Michael McCurrey> wrote: > > > Constructor loading is simple and no magic required. make sure your using the > 1.6.2 source if your using maps that extend maps.... > in your contructor you can then specific Isdirty = false as the last line; > > > > > > > On Fri, May 29, 2009 at 8:45 AM, Sal Bass> wrote: > > > > > > I am using auto properties. I have toyed with ibatis constructor loading, but > because I have never used it on a production app with Ibatis I have been > hesitant. > > > > I may have to resort to using standard properties and go with Yaojin's > solution, or your constructor solution. I have been trying to avoid both of > these but there is no other way....that I can think of. > > > > > > > > ________________________________ > >> Date: Fri, 29 May 2009 08:35:46 -0700 > >> Subject: Re: Dirty Tracking Issue > >> From: [email protected] > >> To: [email protected] > >> > >> Are you in a situation where you can't use constructor loading of your >> objects? If your not using auto-properties (which it seems your not), this >> might solve your problem entirely. > >> > >> On Fri, May 29, 2009 at 8:32 AM, Yaojian> wrote: > >> > >> That is my mistake, the nested objects loaded from the database is not >> touched so they remains its dirty state set by AOP. > >> > >> > >> I think the simplest solution is to map a column to a field instead of a >> property. > >> > >> for example, a C# property: > >> > >> > >> private string m_Name; > >> > >> public String Name > >> { > >> get { return m_Name; } > >> set { m_Name = value; } > >> } > >> > >> we can map the column "Name" to the "m_Name" field rather than the "Name" >> property in SqlMap: > >> > >> > >> > >> > >> > >> So load object from DB will not fire the dirty tracking injiected by AOP. > >> > >> > >> > >> > >> On Fri, May 29, 2009 at 9:19 PM, Sal Bass> wrote: > >> > >> > >> > >> > >> Yaojian, > >> > >> > >> > >> Thanks! I am still confused though. When I make a call to QueryForObject and >> reset the IsLoading flag to false, that only sets it false for the root >> object. All complex property collections that are loaded at the same time >> will not be reset. Am I missing something obvious? > > > > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> ________________________________ > >> > >>> Date: Fri, 29 May 2009 03:52:58 +0800 > >> > >>> Subject: Re: Dirty Tracking Issue > >> > >>> From: [email protected] > >> > >>> To: [email protected] > >> > >>> > >> > >>> If the non-root object is loaded from the database, it should be created >>> with the new object factory. > >> > >>> otherwise, it is irrelavant with 'dirty'. > >> > >>> > >> > >>> Bellow is my code for using IObjectFactory, I use a custom IObjectFactory >>> for attaching each object to a context variable. > >> > >>> > >> > >>> > >> > >>> > >> > >>> DomSqlMapBuilder builder = CreateDomSqlMapBuilder(); > >> > >>> > >> > >>> //Use SqmObjectFactory for attaching objects to the current IObjectContext > >> > >>> IObjectFactory originalFactory = new ObjectFactory(true); > >> > >>> > >> > >>> SqmObjectFactory contextableFactory = new SqmObjectFactory(originalFactory); > >> > >>> builder.ObjectFactory = contextableFactory; > >> > >>> > >> > >>> ISqlMapper sqlMapper = builder.Configure(m_SqlMapDocument); > >> > >>> > >> > >>> > >> > >>> -------------------------------------------------------------------------------------------------------------------------------------------------- > >> > >>> > >> > >>> /// Represents the factory of MDA persistent object used by IBatis.NET. > >> > >>> > >> > >>> /// attaches an > >> > >>> /// to each objects created with this factory. > >> > >>> public class SqmObjectFactory : IObjectFactory, IEntityContextBindable > >> > >>> > >> > >>> { > >> > >>> /// Creates an instance. > >> > >>> /// The original . > >> > >>> public SqmObjectFactory(IObjectFactory objectFactoryImpl) > >> > >>> > >> > >>> { > >> > >>> if (objectFactoryImpl == null) throw new >>> ArgumentNullException("objectFactoryImpl"); > >> > >>> m_ObjectFactoryImpl = objectFactoryImpl; > >> > >>> } > >> > >>> > >> > >>> private readonly IObjectFactory m_ObjectFactoryImpl; > >> > >>> > >> > >>> > >> > >>> private IEntityContext m_EntityContext; > >> > >>> > >> > >>> public IEntityContext EntityContext > >> > >>> { > >> > >>> get { return m_EntityContext; } > >> > >>> set { m_EntityContext = value; } > >> > >>> } > >> > >>> > >> > >>> > >> > >>> /// . > >> > >>> public IFactory CreateFactory(Type typeToCreate, Type[] types) > >> > >>> { > >> > >>> IFactory result = m_ObjectFactoryImpl.CreateFactory(typeToCreate, types); > >> > >>> > >> > >>> if (typeof(IEntityContextBindable).IsAssignableFrom(typeToCreate)) > >> > >>> { > >> > >>> return new SqmFactory(this, result); > >> > >>> } > >> > >>> return result; > >> > >>> } > >> > >>> > >> > >>> private class SqmFactory : IFactory > >> > >>> > >> > >>> { > >> > >>> public SqmFactory(IEntityContextBindable objectContextable, IFactory >>> factory) > >> > >>> { > >> > >>> if (objectContextable == null) throw new >>> ArgumentNullException("objectContextable"); > >> > >>> > >> > >>> if (factory == null) throw new ArgumentNullException("factory"); > >> > >>> > >> > >>> m_ObjectContextable = objectContextable; > >> > >>> m_Factory = factory; > >> > >>> } > >> > >>> > >> > >>> private readonly IEntityContextBindable m_ObjectContextable; > >> > >>> > >> > >>> > >> > >>> private readonly IFactory m_Factory; > >> > >>> > >> > >>> public object CreateInstance(object[] parameters) > >> > >>> { > >> > >>> Object result = m_Factory.CreateInstance(parameters); > >> > >>> ((IEntityContextBindable)result).EntityContext = >>> m_ObjectContextable.EntityContext; > >> > >>> > >> > >>> return result; > >> > >>> } > >> > >>> } > >> > >>> } > >> > >>> > >> > >>> > >> > >>> On Fri, May 29, 2009 at 3:45 AM, Sal Bass> wrote: > >> > >>> > >> > >>> > >> > >>> > >> > >>> Yes, I explored that. But how will that work for the complex properties? >>> Only the root object would know it's in a loading state. > >> > >>> > >> > >>> > >> > >>> > >> > >>> > >> > >>> > >> > >>> ________________________________ > >> > >>> > >> > >>>> Date: Fri, 29 May 2009 02:22:33 +0800 > >> > >>> > >> > >>>> Subject: Re: Dirty Tracking Issue > >> > >>> > >> > >>>> From: [email protected] > >> > >>> > >> > >>>> To: [email protected] > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> We can bypass to set 'dirty' if the AOP generation mechanism can know an >>>> object is in 'loading' state. > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> We can use a custom IBatisNet.Common.Utilities.IObjectFactory to mark an >>>> object 'loading'. > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> And we can use a wrapped ISqlMapper to clean the 'loading' flag as: > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> public object QueryForObject(string statementName, object parameterObject) >>>> { > >> > >>> > >> > >>>> Object result = originalSqlMapper.QueryForObject(...); > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> result.IsLoading = false; > >> > >>> > >> > >>>> return result; > >> > >>> > >> > >>>> } > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> Yaojian > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> On Fri, May 29, 2009 at 1:55 AM, Sal Bass> wrote: > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> I am having a dilema with implementing dirty tracking on my entities. I am >>>> using AOP to mark an entity as "dirty" when a property is set. The problem >>>> occurs when I load the entities using Ibatis because it sets the >>>> properties during mapping which makes the entity dirty (no, I can't use >>>> constructor mapping here). So, I use a RowDelegate to mark the entity >>>> clean before returning it. Works great....except for when I am loading a >>>> root object with several complex properties (ILists of other entities). >>>> The RowDelegate is obviously not fired for each complex property, so they >>>> are returned as dirty. > > > > >> > >> > >> > >>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> Any idea of how I can get at all of the complex properties to mark them >>>> clean before returning the entity? > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> _________________________________________________________________ > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> Hotmail® goes with you. > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> http://windowslive.com/Tutorial/Hotmail/Mobile?ocid=TXT_TAGLM_WL_HM_Tutorial_Mobile1_052009 > > > > >> > >> > >> > >>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>>> > >> > >>> > >> > >>> _________________________________________________________________ > >> > >>> > >> > >>> Windows Live™: Keep your life in sync. > >> > >>> > >> > >>> http://windowslive.com/explore?ocid=TXT_TAGLM_BR_life_in_synch_052009 > >> > >>> > >> > >> _________________________________________________________________ > >> > >> Insert movie times and more without leaving Hotmail®. > >> > >> http://windowslive.com/Tutorial/Hotmail/QuickAdd?ocid=TXT_TAGLM_WL_HM_Tutorial_QuickAdd1_052009 > > > > >> > >> > >> > >> > >> > >> > >> > >> -- > >> Michael J. McCurrey > >> Read with me at http://www.mccurrey.com > > _________________________________________________________________ > > Windows Live™: Keep your life in sync. > > http://windowslive.com/explore?ocid=TXT_TAGLM_BR_life_in_synch_052009 > > > > > > > -- > Michael J. McCurrey > Read with me at http://www.mccurrey.com > > > > _________________________________________________________________ Hotmail® goes with you. http://windowslive.com/Tutorial/Hotmail/Mobile?ocid=TXT_TAGLM_WL_HM_Tutorial_Mobile1_052009

