Elegant solution!   For flexibility, It would be nice to do this either on a
object alias basis or on a resultmap basis in the ibatis source.

On Fri, May 29, 2009 at 9:08 AM, Yaojian <sky...@gmail.com> wrote:

> I have a new solution based on a custom ISetAccessor rather than the
> IObjectFactory.
> As the IBatisNet use ISetAccessor to set the value of a property, we can
> use a custom ISetAccessor saves the IsDirty state before actually set the
> property value and restore it later.
>
> I attach the unit test.
>
> Hope it works for you.
>
>
>
> On Fri, May 29, 2009 at 11:45 PM, Sal Bass <salbass...@hotmail.com> 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: 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
>>
>
>


-- 
Michael J. McCurrey
Read with me at http://www.mccurrey.com

Reply via email to