I finally got a custom type handler working properly (see code below) but I
still contend there is a bug with output parameter mapping in IBatis for
null database values.  In MappedStatement.RetrieveOutputParameters:175
without a custom type handler it uses the UnknownTypeHandler to set the
dataBaseValue object which then blows up in line 178 when it goes to call
SetOutputParameter. I don't really have the time right now to see exactly
why the Set cannot handle the DBNull type as I saw that alot of reflection
and dynamic method instantiation is used for setting values and it would
take me a while to figure out how it works.

   class DbNullTypeHandler : ITypeHandlerCallback
   {

      public void SetParameter(IParameterSetter setter, object parameter)
      {
         if (parameter != null)
         {
            if (parameter.Equals(DateTime.MinValue))
            {
               setter.Value = System.DBNull.Value;
            }
            else
            {
               setter.Value = parameter;
            }
         }
      }

      public object GetResult(IResultGetter getter)
      {
         if (getter.Value.Equals(System.DBNull.Value))
         {
            return NullValue;
         }
         else
         {
            return getter.Value;
         }
      }

      public object ValueOf(string nullValue)
      {
         return nullValue;
      }

      public object NullValue
      {
         get {return null; }
      }
   }



> steve dunning
> Wed, 27 Aug 2008 13:20:13 -0700
>
> I am using a parameter class to encapsulate the input and output
> parameters
> for an Oracle stored procedure that I am calling. When the stored proc
> returns data for all of the Output parameters all is well, however, when
> null values are returned in any of the parameters, well, that is when
> things
> fall apart. It seems that the problem lies somewhere when converting the
> System.DBNull value that is coming back from the database. A
> System.InvalidCastException is thrown for any parameter that contains a
> null.
>
> I found the following JIRA entry
> https://issues.apache.org/jira/browse/IBATISNET-247 that seemed to
> describe
> the problem that I am encountering.  I thought, no problem I will just
> create a custom type handler to manually convert to the right type.
> After
> reading many mail group threads and much experimentation I cannot seem
> to
> get that working either.  Using the type handler then causes valid
> return
> parameters to fail with cast exceptions.
>
> *Any guidance or suggestions would be greatly appreciated!*
>
> *Here is a snippet from my sqlMap config:*
>
>  <alias>
>    <typeAlias alias="DbNullHandler"
> type="Domain.Name.Persistence.Handlers.DbNullTypeHandler,Persistence"/>
>  </alias>
>
>  <parameterMaps>
>    <parameterMap id="tsrHeader-param"
> class="Domain.Name.Persistence.ParameterClasses.TsrHeaderParam,Persisten
> ce"
> >
>      <parameter property="p_req_id"        direction="Input" />
>      <parameter property="date_time_group" direction="Output"
> column="date_time_group" size="100"
>                 />
>                 <!--typeHandler="DbNullHandler" type="DateTime"
> dbType="Date"/>-->
>      <parameter property="message_dest"    direction="Output"
> column="message_dest"    size="1000" />
>      <parameter property="message_origin"  direction="Output"
> column="message_origin"  size="1000" />
>      <parameter property="message_cc"      direction="Output"
> column="message_cc"      size="1000" />
>      <parameter property="return_code"     direction="Output"
> column="return_code"
>                 precision="5" scale="0" size="5" type="Decimal"/>
>    </parameterMap>
>  </parameterMaps>
>
>  <statements>
>    <procedure id="getTsrHeader"  parameterMap="tsrHeader-param">
>      DUNNING_element_tsrHeader
>    </procedure>
>  </statements>
>
> *This is the Custom Type Handler snippet:*
>
>   class DbNullTypeHandler : ITypeHandlerCallback
>   {
>      #region ITypeHandlerCallback Members
>
>      public void SetParameter(IParameterSetter setter, object
> parameter)
>      {
>         if (parameter.Equals(DateTime.MinValue))
>         {
>            setter.Value = System.DBNull.Value;
>         }
>         else
>         {
>            setter.Value = parameter;
>         }
>      }
>
>      public object GetResult(IResultGetter getter)
>      {
>         if (getter.Value.Equals(System.DBNull.Value))
>         {
>            return DateTime.MinValue;
>         }
>         else
>         {
>            return getter.Value;
>         }
>      }
>
>      public object ValueOf(string nullValue)
>      {
>         return nullValue;
>      }
>
>      public object NullValue
>      {
>         get {return System.DBNull.Value; }
>      }
>
> *And this is the parameter class:*
>
>   public class TsrHeaderParam
>   {
>      private string _p_req_id;
>      public string p_req_id
>      {
>         get { return _p_req_id; }
>         set { _p_req_id = value; }
>      }
>
>      private DateTime _date_time_group;
>      public DateTime date_time_group
>      {
>         get { return _date_time_group; }
>         set { _date_time_group = value; }
>      }
>
>      private string _message_origin;
>      public string message_origin
>      {
>         get { return _message_origin; }
>         set { _message_origin = value; }
>      }
>
>      private string _message_dest;
>      public string message_dest
>      {
>         get { return _message_dest; }
>         set { _message_dest = value; }
>      }
>
>      private string _message_cc;
>      public string message_cc
>      {
>         get { return _message_cc; }
>         set { _message_cc = value; }
>      }
>
>      private Decimal _return_code;
>      public Decimal return_code
>      {
>         get { return _return_code; }
>         set { _return_code = value; }
>      }
>   }
> Classification:  UNCLASSIFIED
> Caveats: NONE
>
>

Reply via email to