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: mmccur...@gmail.com > To: user-cs@ibatis.apache.org > > 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: sky...@gmail.com > >> To: user-cs@ibatis.apache.org > >> > >> 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: sky...@gmail.com > >> > >>> To: user-cs@ibatis.apache.org > >> > >>> > >> > >>> 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