You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-java@ibatis.apache.org by Dan Bradley <de...@gmail.com> on 2005/10/06 23:23:30 UTC

Dirty checking

I'm interested in implementing a dirty-checking system. I know that
iBATIS doesn't directly do that, but I'm wondering if anyone else has
developed or thought of a successful approach.

It would be possible of course to add a dirty flag to an entity, then
cause each mutator to set that flag to true. The problem, however, is
that when iBATIS constructs an object (as I understand it) it calls
the mutators. So any object freshly pulled from the database would be
incorrectly marked as dirty.

If iBATIS guarantees the order it calls on setters based on the order
they appear in the mapping, then it seems it would be possible to
effectively add a setDirty(false) in the result map as the last result
map property. But does iBATIS make this guarantee?

If not, another approach would be to use some sort of listener or hook
into an event system so that after iBATIS loads an object, I could tie
in some code that reset the dirty flag on the object. Does iBATIS have
any such hooks?

Or is there yet another way to make dirty checking work on top of
iBATIS? Thanks for any ideas.

Re: Dirty checking

Posted by Dan Bradley <de...@gmail.com>.
I had considered having the DAO reset the entity's dirty flag, but
that won't work for lazy-loaded relationships. For example a Location
entity is related to a Country entity through a select query:

<resultMap id="location-result" class="com.foo.Location">
    <result property="country" column="country_id" select="getCountryById" />
</resultMap>

The Country entity then is not loaded by the Location DAO or the
Country DAO for that matter. The Location DAO loads the requested
location and sets its dirty flag to false. Country is loaded by
iBatis, not the DAO, the first time a client calls
location.getCountry(), and country is now incorrectly marked as dirty.

This is why some sort of hook into the iBatis event system seems
required. Anyone know if this is possible, or how to work around it?

Thanks.

On 10/6/05, Ben Munat <be...@munat.com> wrote:
> Just have your DAO set the entity's dirty flag to false before handing back the created
> object.
>
> My co-worker wrote a little DTO generator and it creates setter methods like this:
>
> public void setFoo(Object foo)
> {
>      if(((this.foo != null) && !this.foo.equals(foo))
>              || ((this.foo == null) && (foo != null))) {
>          dirty = true;
>          this.foo = foo;
>      }
> }
>
> The base class for all DTOs also has a setDirty(boolean) method. So, the DAO creates the
> object, sets all the values, and then sets dirty to false. Then, after that, any call to a
> setter that actually changes a non-null value sets the dirty flag.
>
> There might be a better way out there, but that's what we've done on several projects and
> it works ok.
>
> b
>
>
> Dan Bradley wrote:
> > I'm interested in implementing a dirty-checking system. I know that
> > iBATIS doesn't directly do that, but I'm wondering if anyone else has
> > developed or thought of a successful approach.
> >
> > It would be possible of course to add a dirty flag to an entity, then
> > cause each mutator to set that flag to true. The problem, however, is
> > that when iBATIS constructs an object (as I understand it) it calls
> > the mutators. So any object freshly pulled from the database would be
> > incorrectly marked as dirty.
> >
> > If iBATIS guarantees the order it calls on setters based on the order
> > they appear in the mapping, then it seems it would be possible to
> > effectively add a setDirty(false) in the result map as the last result
> > map property. But does iBATIS make this guarantee?
> >
> > If not, another approach would be to use some sort of listener or hook
> > into an event system so that after iBATIS loads an object, I could tie
> > in some code that reset the dirty flag on the object. Does iBATIS have
> > any such hooks?
> >
> > Or is there yet another way to make dirty checking work on top of
> > iBATIS? Thanks for any ideas.
>

Re: Dirty checking

Posted by Ben Munat <be...@munat.com>.
Just have your DAO set the entity's dirty flag to false before handing back the created 
object.

My co-worker wrote a little DTO generator and it creates setter methods like this:

public void setFoo(Object foo)
{
     if(((this.foo != null) && !this.foo.equals(foo))
             || ((this.foo == null) && (foo != null))) {
         dirty = true;
         this.foo = foo;
     }
}

The base class for all DTOs also has a setDirty(boolean) method. So, the DAO creates the 
object, sets all the values, and then sets dirty to false. Then, after that, any call to a 
setter that actually changes a non-null value sets the dirty flag.

There might be a better way out there, but that's what we've done on several projects and 
it works ok.

b


Dan Bradley wrote:
> I'm interested in implementing a dirty-checking system. I know that
> iBATIS doesn't directly do that, but I'm wondering if anyone else has
> developed or thought of a successful approach.
> 
> It would be possible of course to add a dirty flag to an entity, then
> cause each mutator to set that flag to true. The problem, however, is
> that when iBATIS constructs an object (as I understand it) it calls
> the mutators. So any object freshly pulled from the database would be
> incorrectly marked as dirty.
> 
> If iBATIS guarantees the order it calls on setters based on the order
> they appear in the mapping, then it seems it would be possible to
> effectively add a setDirty(false) in the result map as the last result
> map property. But does iBATIS make this guarantee?
> 
> If not, another approach would be to use some sort of listener or hook
> into an event system so that after iBATIS loads an object, I could tie
> in some code that reset the dirty flag on the object. Does iBATIS have
> any such hooks?
> 
> Or is there yet another way to make dirty checking work on top of
> iBATIS? Thanks for any ideas.