You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-cs@ibatis.apache.org by Ka-Wai Chan <Ka...@huskyenergy.ca> on 2007/01/22 22:46:52 UTC

mapping 1 to 0 or 1 relationships to null objects

Hello
 
I have a 1 to 0 or 1 relationship mapped as follow
 
      <result property="SubObject" column="sub_object_id"
select="SelectBySubtObjectId"/>
 
This works fine, but what we are trying to implement is the NullObject
pattern in which a null value is mapped to a specific null object
instead of null.
 
ie.  In Parent object, I have a reference called SubObject.  Ibatis
right now will set that reference to null when a database value of null
is encountered, what I want is for Ibatis to set that value to
SubObject.NULL instead.
 
Is this possible? What is the proper way of doing this?  
 
I have tried implementing ITypeHandlerCallback by doing the following
but doesn't work.  When is the NullValue getter called?
 
        public void SetParameter(IParameterSetter setter, object
parameter)
        {
        }
 
        public object GetResult(IResultGetter getter)
        {
            return getter.Value;
        }
 
        public object ValueOf(string s)
        {
            return s;
        }
 
        public object NullValue
        {
            get { return SubObject.NULL; }
        }
 
Thanks, 
Ka-Wai 

Re: mapping 1 to 0 or 1 relationships to null objects

Posted by Clinton Begin <cl...@gammagarage.com>.
NullObject pattern eh?  I'll reserve judgment and admit that I have no
idea what you're doing.  But I'll bet you lunch that you'll be ripping
it out later.  ;-)

Anyway...now for the helpful part of my response:

If you can, I'd suggest making it impossible for relations to be null
right at the database level.  That is, there's no nullable foreign
keys allowed.  Not only will it solve this problem, but it will avoid
outer joins and increase query performance in many cases.

Otherwise...

Since Castle Dynamic Proxy is on your classpath anyway (iBATIS.NET
uses it for lazy loading), you can use it to intercept setters and
have the proxy do this for you.  Alternatively, you might be able to
plug in your own null setting logic using a custom type handler (but
I'm not sure how similar the iBATIS.NET is to iBATIS for Java in this
respect).  Finally (as in my last idea), you could put a static (i.e.
normal) proxy/decorator between the DataMapper interface and the real
iBATIS implementation that checks all objects on their way out for
properties of complex types with null values.

Smart assed comments aside, I hope that helps!

Cheers,
Clinton

On 1/22/07, Ka-Wai Chan <Ka...@huskyenergy.ca> wrote:
>
>
> Thanks Peter
>
> We are doing something similar now, was just wondering if this could be
> avoided by handling it in IBatis.
>
> Thanks
> Ka-Wai
>
> >>> Peter Mills <de...@peter.mills.to> 01/22/07 4:24 PM >>>
>
> Hi Ka-Wai,
>
> I find the easiest way to do that kind of mapping is in the domain
> object, itself.
>
> public class Customer {
>     SubObject _subObject = SubObject.Empty;
>
>     public SubObject MySubObject {
>        get { return _subObject; }
>        set {
>           if (null == value)
>              _subObject = SubObject.Empty;
>           else
>              _subObject = value;
>        }
>     }
> }
>
> It also protects you from accidentally setting the property null,
> somewhere else in your code.
>
> Cheers,
>
> Peter
>
> Ka-Wai Chan wrote:
> > Hello
> >
> > I have a 1 to 0 or 1 relationship mapped as follow
> >
> >       <result property="SubObject" column="sub_object_id"
> > select="SelectBySubtObjectId"/>
> >
> > This works fine, but what we are trying to implement is the NullObject
> > pattern in which a null value is mapped to a specific null object
> > instead of null.
> >
> > ie.  In Parent object, I have a reference called SubObject.  Ibatis
> > right now will set that reference to null when a database value of
> > null is encountered, what I want is for Ibatis to set that value to
> > SubObject.NULL instead.
> >
> > Is this possible? What is the proper way of doing this?
> >
> > I have tried implementing ITypeHandlerCallback by doing the following
> > but doesn't work.  When is the NullValue getter called?
> >
> >  &nbsp ;      public void SetParameter(IParameterSetter setter, object
> > parameter)
> >         {
> >         }
> >
> >         public object GetResult(IResultGetter getter)
> >         {
> >             return getter.Value;
> >         }
> >
> >         public object ValueOf(string s)
> >         {
> >             return s;
> >         }
> >
> >         public object NullValue
> >   & nbsp;     {
> >             get { return SubObject.NULL; }
> >         }
> >
> > Thanks,
> > Ka-Wai
>
>

Re: mapping 1 to 0 or 1 relationships to null objects

Posted by Ka-Wai Chan <Ka...@huskyenergy.ca>.
Thanks Peter
 
We are doing something similar now, was just wondering if this could be
avoided by handling it in IBatis.
 
Thanks
Ka-Wai

>>> Peter Mills <de...@peter.mills.to> 01/22/07 4:24 PM >>>

Hi Ka-Wai,

I find the easiest way to do that kind of mapping is in the domain 
object, itself.

public class Customer {
    SubObject _subObject = SubObject.Empty;

    public SubObject MySubObject {
       get { return _subObject; }
       set {
          if (null == value)
             _subObject = SubObject.Empty;
          else
             _subObject = value;
       }
    }
}

It also protects you from accidentally setting the property null, 
somewhere else in your code.

Cheers,

Peter

Ka-Wai Chan wrote:
> Hello
>  
> I have a 1 to 0 or 1 relationship mapped as follow
>  
>       <result property="SubObject" column="sub_object_id" 
> select="SelectBySubtObjectId"/>
>  
> This works fine, but what we are trying to implement is the
NullObject 
> pattern in which a null value is mapped to a specific null object 
> instead of null.
>  
> ie.  In Parent object, I have a reference called SubObject.  Ibatis 
> right now will set that reference to null when a database value of 
> null is encountered, what I want is for Ibatis to set that value to 
> SubObject.NULL instead.
>  
> Is this possible? What is the proper way of doing this? 
>  
> I have tried implementing ITypeHandlerCallback by doing the following

> but doesn't work.  When is the NullValue getter called?
>  
>         public void SetParameter(IParameterSetter setter, object 
> parameter)
>         {
>         }
>  
>         public object GetResult(IResultGetter getter)
>         {
>             return getter.Value;
>         }
>  
>         public object ValueOf(string s)
>         {
>             return s;
>         }
>  
>         public object NullValue
>         {
>             get { return SubObject.NULL; }
>         }
>  
> Thanks,
> Ka-Wai



Re: mapping 1 to 0 or 1 relationships to null objects

Posted by Peter Mills <de...@peter.mills.to>.
Hi Ka-Wai,

I find the easiest way to do that kind of mapping is in the domain 
object, itself.

public class Customer {
    SubObject _subObject = SubObject.Empty;

    public SubObject MySubObject {
       get { return _subObject; }
       set {
          if (null == value)
             _subObject = SubObject.Empty;
          else
             _subObject = value;
       }
    }
}

It also protects you from accidentally setting the property null, 
somewhere else in your code.

Cheers,

Peter

Ka-Wai Chan wrote:
> Hello
>  
> I have a 1 to 0 or 1 relationship mapped as follow
>  
>       <result property="SubObject" column="sub_object_id" 
> select="SelectBySubtObjectId"/>
>  
> This works fine, but what we are trying to implement is the NullObject 
> pattern in which a null value is mapped to a specific null object 
> instead of null.
>  
> ie.  In Parent object, I have a reference called SubObject.  Ibatis 
> right now will set that reference to null when a database value of 
> null is encountered, what I want is for Ibatis to set that value to 
> SubObject.NULL instead.
>  
> Is this possible? What is the proper way of doing this? 
>  
> I have tried implementing ITypeHandlerCallback by doing the following 
> but doesn't work.  When is the NullValue getter called?
>  
>         public void SetParameter(IParameterSetter setter, object 
> parameter)
>         {
>         }
>  
>         public object GetResult(IResultGetter getter)
>         {
>             return getter.Value;
>         }
>  
>         public object ValueOf(string s)
>         {
>             return s;
>         }
>  
>         public object NullValue
>         {
>             get { return SubObject.NULL; }
>         }
>  
> Thanks,
> Ka-Wai