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

Reply via email to