Hi Ron.

The reason for the issue with the null dbType not working out is that the TypeHandlerFactory registers the DataMapper's BooleanTypeHandler for NULL ("_NULL_TYPE_") dbTypes on startup.

When the custom typehandler is loaded and goes through this (NULL is the private const string NULL = "_NULL_TYPE_"):

>  if (dbType==null)
>  {
>   map.Add(NULL, handler); // line 200
>  }

...the exception is thrown because there is already a key/value for NULL ("_NULL_TYPE_").

I guess the code could be modded to something like this (and also for the "else" part of the dbType=null "if") to overwrite the HybridDictionary with the new typehandler:

            if (dbType==null)
            {
                if (map.Contains(NULL))
                {
                    map.Remove(NULL);
                    map.Add(NULL, handler);   
                }
                else
                {
                    map.Add(NULL, handler);   
                }
            }

Then anywhere the DataMapper will use the custom typehandler (or the last typehandler specified actually) for all types that don't have a dbType defined in a <result>.

I did do a quick test to see this work in the following, but I'm not sure if there would be unwanted side-effects though:

SqlMap_Oracle_OracleClient.config
    <typeHandlers>
        <typeHandler type="bool" callback="OuiNonBool"/>
        <!-- <typeHandler type="bool" dbType="VarChar" callback="OuiNonBool"/> -->
    </typeHandlers>

Oracle OracleClient Account.xml
<result property="BannerOption" column="Account_Banner_Option"/>
<!-- <result property="BannerOption" column="Account_Banner_Option" dbType="VarChar" type="bool"/> -->

Hope this helps!

Roberto





On 10/3/05, Ron Grabowski <[EMAIL PROTECTED]> wrote:
I still haven't found a solution to this. If I'm working with a legacy
database that stores 'Y' for boolean true and 'N' for boolean false can
I have override IBatisNet.DataMapper.TypeHandlers.BooleanTypeHandler
with my own type handler so its used globally for all resultMaps and
parameterMaps?

--- Ron Grabowski <[EMAIL PROTECTED]> wrote:

> I want to implement a typeHandler for DateTime objects that overrides
> the default DateTimeTypeHandler. I've added this text to my
> sqlMap.config file:
>
>  <typeHandlers>
>   <typeHandler
>    type="DateTime"
>    callback=" Company.Project.DataMapper.MyDateTimeTypeHandler" />
>  </typeHandlers>
>
> This is the implementation:
>
> public class MyDateTimeTypeHandler : ITypeHandlerCallback
> {
>  public object ValueOf(string nullValue)
>  {
>   // ???
>   return Convert.ToDateTime(nullValue);
>  }
>
>  public object GetResult(IResultGetter getter)
>  {
>   if ( getter.Value.Equals(System.DBNull.Value))
>   {
>    return DateTime.MinValue;
>   }
>   else
>   {
>    return getter.Value;
>   }
>  }
>
>  public void SetParameter(IParameterSetter setter, object parameter)
>  {
>   if (parameter.Equals(DateTime.MinValue))
>   {
>    setter.Value = System.DBNull.Value;
>   }
>   else
>   {
>    setter.Value = parameter;
>   }
>  }
> }
>
> The MyDateTimeTypeHandler class is ignored if I don't specify a
> dbType
> attribute. If I do supply one:
>
>  dbType="System.Data.OleDb.OleDbType"
>
> I get a NullReferenceException on line 200 of TypeHanlderFactory.cs:
>
> public void Register(Type type, string dbType, ITypeHandler handler)
> {
>  HybridDictionary map = (HybridDictionary)_typeHandlerMap[type];
>  if (map == null)
>  {
>   map = new HybridDictionary();
>   _typeHandlerMap.Add(type, map);
>  }
>  if (dbType==null)
>  {
>   map.Add(NULL, handler); // line 200
>  }
>  else
>  {
>   map.Add(dbType, handler);
>  }
> }
>
> Yes, I've seen the TestCustomTypeHandler test case. That requires me
> to
> specify a typeHandler attribute on the result and parameter nodes:
>
>  <result
>   property="Bool2"
>   column="Other_String"
>   typeHandler="OuiNonBool" />
>
> I don't want to do that. I want MyDateTimeTypeHandler to replace the
> DateTimeTypeHandler in all cases automatically.
>
> Ideas?
>
> Thanks,
> Ron
>


Reply via email to