Thanks for the information. I think it would be good to allow the user
to override the default type handlers. Imagine if you were working on a
legacy system where "Y" was always used for true and "N" was always
used for false. Instead of having to specify a custom type handler on
all the result/parameter maps it would be nice if I could override the
default type handler have the system automatically use it. If that were
possible, there would also need to be a way to go back to IBatisNet's
type handlers for special cases (for new tables that use true/false
correctly). Perhaps the IBatisNet type handlers should be changed from
internal to public?
In my case I want all DateTime.MinValue values sent as parameters to be
automatically converted to System.DBNull.Value and all
System.DBNull.Value values returned from the database to be
automatically converted into DateTime.MinValue. Of course this only
applies to DateTime columns. Currently, when I pass a DateTime.MinValue
into a statement it tries to insert 1/1/0001 00:00:00 AM which is not a
valid date for most databases.
Is there a better way to deal with NULL/DateTime.MinValues?
--- Roberto R <[EMAIL PROTECTED]> wrote:
> 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
> > >
> >
> >
>