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 Nathan Maves <Na...@Sun.COM> on 2005/03/03 17:46:33 UTC

Bug with CTH and order of a ResultMap

Team,

I know that this was not the intended way to use CTH but it works 99% 
of the time!

The 1% of the time that it fails is really strange.  It will only fail 
if the column before it in the result map is null.  In the example 
below I can get it to work if I move the line

	<result property="timeZone" column="time_zone"/>

after a result that is NOT null.

I am not sure why this is happening.  I thought that the order of the 
result map meant nothing.

Nathan

SqlMapConfig

	<typeAlias alias="TimeZone" 
type="giveservice.domain.definitions.TimeZone"/>

     <typeHandler javaType="TimeZone" 
callback="giveservice.dao.ibatis.typeHandler.TimeZoneCTH"/>


CTH
	public class TimeZoneCTH implements TypeHandlerCallback {

     public Object getResult(ResultGetter getter) throws SQLException {
         if (getter.wasNull())
             return null;
         int value = getter.getInt();
         return TimeZone.findEnumeration(value);
     }

     public void setParameter(ParameterSetter setter, Object parameter) 
throws SQLException {
         if (parameter == null) {
             setter.setNull(Types.INTEGER);
         } else {
             TimeZone param = (TimeZone) parameter;
             setter.setInt(param.getDatabaseId());
         }
     }

     public Object valueOf(String s){
         return s;
     }

}

ResultMap Working

	<resultMap id="simpleRequestResultMap" class="Request">
         <result property="id" column="id"/>
         ...
         <result property="partner" column="partner"/>
         <result property="partnerName" column="partner_name"/>
         <result property="partnerEmail" column="partner_email"/>
         <result property="partnerPhone" column="partner_phone"/>
         <result property="contractNumber" column="contract_number"/>
         <result property="timeZone" column="time_zone"/>
         ...
     </resultMap>

ResultMap NOT Working! < Notice the order in regards to the time_zone 
column >

	<resultMap id="simpleRequestResultMap" class="Request">
         <result property="id" column="id"/>
         ...
         <result property="partner" column="partner"/>
         <result property="partnerName" column="partner_name"/>
         <result property="partnerEmail" column="partner_email"/>
         <result property="partnerPhone" column="partner_phone"/>
		<result property="timeZone" column="time_zone"/>
         <result property="contractNumber" column="contract_number"/>
         ...
     </resultMap>


Re: Bug with CTH and order of a ResultMap

Posted by Clinton Begin <cl...@gmail.com>.
Awesome.  Thanks Nathan!


On Tue, 08 Mar 2005 00:07:58 -0700, Nathan Maves <Na...@sun.com> wrote:
> BTW I have updated the FAQ about CTH on the wiki as well.
> 
> Nathan
> On Mar 8, 2005, at 12:02 AM, Nathan Maves wrote:
> 
> > Jean-Francois,
> >
> > You are once again the answer man!
> >
> > I am not sure how those lines got switched around but that did the
> > trick.  After changing about 8 CTH and running my unit tests,
> > everything runs perfect.
> >
> > Nathan
> > On Mar 7, 2005, at 5:18 PM, Jean-Francois Poilpret wrote:
> >
> >> Hello Nathan,
> >>
> >> The answer to this problem is easy: iBATIS ResultGetter is just a
> >> wrapper
> >> around JDBC ResultSet getter methods.
> >> If you have a look at the JDBC doc, you will see that wasNull() must
> >> be
> >> called _after_ getXxxx() for one given column, ie, wasNull() will
> >> tell you
> >> if the _last column you have read_ was null or not (not the column
> >> you are
> >> about to read).
> >>
> >> So you should write your CTH that way:
> >>      public Object getResult(ResultGetter getter) throws SQLException
> >> {
> >>          int value = getter.getInt();
> >>          if (getter.wasNull())
> >>              return null;
> >>          return TimeZone.findEnumeration(value);
> >>      }
> >>
> >> That's all!
> >> By the way, thank you for reporting this problem: I have coded my own
> >> CTH
> >> the same way, but I could not exhibit this problem because in fact,
> >> the
> >> current column and the previous column in my own table are not
> >> nullable.
> >>
> >> Cheers
> >>
> >>      Jean-Francois
> >>
> >> -----Original Message-----
> >> From: Nathan Maves [mailto:Nathan.Maves@Sun.COM]
> >> Sent: Tuesday, March 08, 2005 3:48 AM
> >> To: ibatis-user-java@incubator.apache.org
> >> Subject: Re: Bug with CTH and order of a ResultMap
> >>
> >> Anyone had a chance to look at this issue yet?
> >>
> >>      Nathan
> >>
> >> On Mar 3, 2005, at 9:46 AM, Nathan Maves wrote:
> >>
> >>> Team,
> >>>
> >>> I know that this was not the intended way to use CTH but it works 99%
> >>> of the time!
> >>>
> >>> The 1% of the time that it fails is really strange.  It will only
> >>> fail
> >>> if the column before it in the result map is null.  In the example
> >>> below I can get it to work if I move the line
> >>>
> >>>     <result property="timeZone" column="time_zone"/>
> >>>
> >>> after a result that is NOT null.
> >>>
> >>> I am not sure why this is happening.  I thought that the order of the
> >>> result map meant nothing.
> >>>
> >>> Nathan
> >>>
> >>> SqlMapConfig
> >>>
> >>>     <typeAlias alias="TimeZone"
> >>> type="giveservice.domain.definitions.TimeZone"/>
> >>>
> >>>     <typeHandler javaType="TimeZone"
> >>> callback="giveservice.dao.ibatis.typeHandler.TimeZoneCTH"/>
> >>>
> >>>
> >>> CTH
> >>>     public class TimeZoneCTH implements TypeHandlerCallback {
> >>>
> >>>     public Object getResult(ResultGetter getter) throws SQLException
> >>> {
> >>>         if (getter.wasNull())
> >>>             return null;
> >>>         int value = getter.getInt();
> >>>         return TimeZone.findEnumeration(value);
> >>>     }
> >>>
> >>>     public void setParameter(ParameterSetter setter, Object
> >>> parameter)
> >>> throws SQLException {
> >>>         if (parameter == null) {
> >>>             setter.setNull(Types.INTEGER);
> >>>         } else {
> >>>             TimeZone param = (TimeZone) parameter;
> >>>             setter.setInt(param.getDatabaseId());
> >>>         }
> >>>     }
> >>>
> >>>     public Object valueOf(String s){
> >>>         return s;
> >>>     }
> >>>
> >>> }
> >>>
> >>> ResultMap Working
> >>>
> >>>     <resultMap id="simpleRequestResultMap" class="Request">
> >>>         <result property="id" column="id"/>
> >>>         ...
> >>>         <result property="partner" column="partner"/>
> >>>         <result property="partnerName" column="partner_name"/>
> >>>         <result property="partnerEmail" column="partner_email"/>
> >>>         <result property="partnerPhone" column="partner_phone"/>
> >>>         <result property="contractNumber" column="contract_number"/>
> >>>         <result property="timeZone" column="time_zone"/>
> >>>         ...
> >>>     </resultMap>
> >>>
> >>> ResultMap NOT Working! < Notice the order in regards to the time_zone
> >>> column >
> >>>
> >>>     <resultMap id="simpleRequestResultMap" class="Request">
> >>>         <result property="id" column="id"/>
> >>>         ...
> >>>         <result property="partner" column="partner"/>
> >>>         <result property="partnerName" column="partner_name"/>
> >>>         <result property="partnerEmail" column="partner_email"/>
> >>>         <result property="partnerPhone" column="partner_phone"/>
> >>>             <result property="timeZone" column="time_zone"/>
> >>>         <result property="contractNumber" column="contract_number"/>
> >>>         ...
> >>>     </resultMap>
> >>>
> >>
> >>
> >>
> >
> 
>

Re: Bug with CTH and order of a ResultMap

Posted by Nathan Maves <Na...@Sun.COM>.
BTW I have updated the FAQ about CTH on the wiki as well.

Nathan
On Mar 8, 2005, at 12:02 AM, Nathan Maves wrote:

> Jean-Francois,
>
> You are once again the answer man!
>
> I am not sure how those lines got switched around but that did the 
> trick.  After changing about 8 CTH and running my unit tests, 
> everything runs perfect.
>
> Nathan
> On Mar 7, 2005, at 5:18 PM, Jean-Francois Poilpret wrote:
>
>> Hello Nathan,
>>
>> The answer to this problem is easy: iBATIS ResultGetter is just a 
>> wrapper
>> around JDBC ResultSet getter methods.
>> If you have a look at the JDBC doc, you will see that wasNull() must 
>> be
>> called _after_ getXxxx() for one given column, ie, wasNull() will 
>> tell you
>> if the _last column you have read_ was null or not (not the column 
>> you are
>> about to read).
>>
>> So you should write your CTH that way:
>>      public Object getResult(ResultGetter getter) throws SQLException 
>> {
>>          int value = getter.getInt();
>>          if (getter.wasNull())
>>              return null;
>>          return TimeZone.findEnumeration(value);
>>      }
>>
>> That's all!
>> By the way, thank you for reporting this problem: I have coded my own 
>> CTH
>> the same way, but I could not exhibit this problem because in fact, 
>> the
>> current column and the previous column in my own table are not 
>> nullable.
>>
>> Cheers
>>
>> 	Jean-Francois
>>
>> -----Original Message-----
>> From: Nathan Maves [mailto:Nathan.Maves@Sun.COM]
>> Sent: Tuesday, March 08, 2005 3:48 AM
>> To: ibatis-user-java@incubator.apache.org
>> Subject: Re: Bug with CTH and order of a ResultMap
>>
>> Anyone had a chance to look at this issue yet?
>>
>> 	Nathan
>>
>> On Mar 3, 2005, at 9:46 AM, Nathan Maves wrote:
>>
>>> Team,
>>>
>>> I know that this was not the intended way to use CTH but it works 99%
>>> of the time!
>>>
>>> The 1% of the time that it fails is really strange.  It will only 
>>> fail
>>> if the column before it in the result map is null.  In the example
>>> below I can get it to work if I move the line
>>>
>>> 	<result property="timeZone" column="time_zone"/>
>>>
>>> after a result that is NOT null.
>>>
>>> I am not sure why this is happening.  I thought that the order of the
>>> result map meant nothing.
>>>
>>> Nathan
>>>
>>> SqlMapConfig
>>>
>>> 	<typeAlias alias="TimeZone"
>>> type="giveservice.domain.definitions.TimeZone"/>
>>>
>>>     <typeHandler javaType="TimeZone"
>>> callback="giveservice.dao.ibatis.typeHandler.TimeZoneCTH"/>
>>>
>>>
>>> CTH
>>> 	public class TimeZoneCTH implements TypeHandlerCallback {
>>>
>>>     public Object getResult(ResultGetter getter) throws SQLException 
>>> {
>>>         if (getter.wasNull())
>>>             return null;
>>>         int value = getter.getInt();
>>>         return TimeZone.findEnumeration(value);
>>>     }
>>>
>>>     public void setParameter(ParameterSetter setter, Object 
>>> parameter)
>>> throws SQLException {
>>>         if (parameter == null) {
>>>             setter.setNull(Types.INTEGER);
>>>         } else {
>>>             TimeZone param = (TimeZone) parameter;
>>>             setter.setInt(param.getDatabaseId());
>>>         }
>>>     }
>>>
>>>     public Object valueOf(String s){
>>>         return s;
>>>     }
>>>
>>> }
>>>
>>> ResultMap Working
>>>
>>> 	<resultMap id="simpleRequestResultMap" class="Request">
>>>         <result property="id" column="id"/>
>>>         ...
>>>         <result property="partner" column="partner"/>
>>>         <result property="partnerName" column="partner_name"/>
>>>         <result property="partnerEmail" column="partner_email"/>
>>>         <result property="partnerPhone" column="partner_phone"/>
>>>         <result property="contractNumber" column="contract_number"/>
>>>         <result property="timeZone" column="time_zone"/>
>>>         ...
>>>     </resultMap>
>>>
>>> ResultMap NOT Working! < Notice the order in regards to the time_zone
>>> column >
>>>
>>> 	<resultMap id="simpleRequestResultMap" class="Request">
>>>         <result property="id" column="id"/>
>>>         ...
>>>         <result property="partner" column="partner"/>
>>>         <result property="partnerName" column="partner_name"/>
>>>         <result property="partnerEmail" column="partner_email"/>
>>>         <result property="partnerPhone" column="partner_phone"/>
>>> 		<result property="timeZone" column="time_zone"/>
>>>         <result property="contractNumber" column="contract_number"/>
>>>         ...
>>>     </resultMap>
>>>
>>
>>
>>
>


Re: Bug with CTH and order of a ResultMap

Posted by Nathan Maves <Na...@Sun.COM>.
Jean-Francois,

You are once again the answer man!

I am not sure how those lines got switched around but that did the 
trick.  After changing about 8 CTH and running my unit tests, 
everything runs perfect.

Nathan
On Mar 7, 2005, at 5:18 PM, Jean-Francois Poilpret wrote:

> Hello Nathan,
>
> The answer to this problem is easy: iBATIS ResultGetter is just a 
> wrapper
> around JDBC ResultSet getter methods.
> If you have a look at the JDBC doc, you will see that wasNull() must be
> called _after_ getXxxx() for one given column, ie, wasNull() will tell 
> you
> if the _last column you have read_ was null or not (not the column you 
> are
> about to read).
>
> So you should write your CTH that way:
>      public Object getResult(ResultGetter getter) throws SQLException {
>          int value = getter.getInt();
>          if (getter.wasNull())
>              return null;
>          return TimeZone.findEnumeration(value);
>      }
>
> That's all!
> By the way, thank you for reporting this problem: I have coded my own 
> CTH
> the same way, but I could not exhibit this problem because in fact, the
> current column and the previous column in my own table are not 
> nullable.
>
> Cheers
>
> 	Jean-Francois
>
> -----Original Message-----
> From: Nathan Maves [mailto:Nathan.Maves@Sun.COM]
> Sent: Tuesday, March 08, 2005 3:48 AM
> To: ibatis-user-java@incubator.apache.org
> Subject: Re: Bug with CTH and order of a ResultMap
>
> Anyone had a chance to look at this issue yet?
>
> 	Nathan
>
> On Mar 3, 2005, at 9:46 AM, Nathan Maves wrote:
>
>> Team,
>>
>> I know that this was not the intended way to use CTH but it works 99%
>> of the time!
>>
>> The 1% of the time that it fails is really strange.  It will only fail
>> if the column before it in the result map is null.  In the example
>> below I can get it to work if I move the line
>>
>> 	<result property="timeZone" column="time_zone"/>
>>
>> after a result that is NOT null.
>>
>> I am not sure why this is happening.  I thought that the order of the
>> result map meant nothing.
>>
>> Nathan
>>
>> SqlMapConfig
>>
>> 	<typeAlias alias="TimeZone"
>> type="giveservice.domain.definitions.TimeZone"/>
>>
>>     <typeHandler javaType="TimeZone"
>> callback="giveservice.dao.ibatis.typeHandler.TimeZoneCTH"/>
>>
>>
>> CTH
>> 	public class TimeZoneCTH implements TypeHandlerCallback {
>>
>>     public Object getResult(ResultGetter getter) throws SQLException {
>>         if (getter.wasNull())
>>             return null;
>>         int value = getter.getInt();
>>         return TimeZone.findEnumeration(value);
>>     }
>>
>>     public void setParameter(ParameterSetter setter, Object parameter)
>> throws SQLException {
>>         if (parameter == null) {
>>             setter.setNull(Types.INTEGER);
>>         } else {
>>             TimeZone param = (TimeZone) parameter;
>>             setter.setInt(param.getDatabaseId());
>>         }
>>     }
>>
>>     public Object valueOf(String s){
>>         return s;
>>     }
>>
>> }
>>
>> ResultMap Working
>>
>> 	<resultMap id="simpleRequestResultMap" class="Request">
>>         <result property="id" column="id"/>
>>         ...
>>         <result property="partner" column="partner"/>
>>         <result property="partnerName" column="partner_name"/>
>>         <result property="partnerEmail" column="partner_email"/>
>>         <result property="partnerPhone" column="partner_phone"/>
>>         <result property="contractNumber" column="contract_number"/>
>>         <result property="timeZone" column="time_zone"/>
>>         ...
>>     </resultMap>
>>
>> ResultMap NOT Working! < Notice the order in regards to the time_zone
>> column >
>>
>> 	<resultMap id="simpleRequestResultMap" class="Request">
>>         <result property="id" column="id"/>
>>         ...
>>         <result property="partner" column="partner"/>
>>         <result property="partnerName" column="partner_name"/>
>>         <result property="partnerEmail" column="partner_email"/>
>>         <result property="partnerPhone" column="partner_phone"/>
>> 		<result property="timeZone" column="time_zone"/>
>>         <result property="contractNumber" column="contract_number"/>
>>         ...
>>     </resultMap>
>>
>
>
>


RE: Bug with CTH and order of a ResultMap

Posted by Jean-Francois Poilpret <jf...@hcm.vnn.vn>.
Hello Nathan,

The answer to this problem is easy: iBATIS ResultGetter is just a wrapper
around JDBC ResultSet getter methods.
If you have a look at the JDBC doc, you will see that wasNull() must be
called _after_ getXxxx() for one given column, ie, wasNull() will tell you
if the _last column you have read_ was null or not (not the column you are
about to read).

So you should write your CTH that way:
     public Object getResult(ResultGetter getter) throws SQLException {
         int value = getter.getInt();
         if (getter.wasNull())
             return null;
         return TimeZone.findEnumeration(value);
     }

That's all! 
By the way, thank you for reporting this problem: I have coded my own CTH
the same way, but I could not exhibit this problem because in fact, the
current column and the previous column in my own table are not nullable.

Cheers

	Jean-Francois

-----Original Message-----
From: Nathan Maves [mailto:Nathan.Maves@Sun.COM] 
Sent: Tuesday, March 08, 2005 3:48 AM
To: ibatis-user-java@incubator.apache.org
Subject: Re: Bug with CTH and order of a ResultMap

Anyone had a chance to look at this issue yet?

	Nathan

On Mar 3, 2005, at 9:46 AM, Nathan Maves wrote:

> Team,
>
> I know that this was not the intended way to use CTH but it works 99% 
> of the time!
>
> The 1% of the time that it fails is really strange.  It will only fail 
> if the column before it in the result map is null.  In the example 
> below I can get it to work if I move the line
>
> 	<result property="timeZone" column="time_zone"/>
>
> after a result that is NOT null.
>
> I am not sure why this is happening.  I thought that the order of the 
> result map meant nothing.
>
> Nathan
>
> SqlMapConfig
>
> 	<typeAlias alias="TimeZone" 
> type="giveservice.domain.definitions.TimeZone"/>
>
>     <typeHandler javaType="TimeZone" 
> callback="giveservice.dao.ibatis.typeHandler.TimeZoneCTH"/>
>
>
> CTH
> 	public class TimeZoneCTH implements TypeHandlerCallback {
>
>     public Object getResult(ResultGetter getter) throws SQLException {
>         if (getter.wasNull())
>             return null;
>         int value = getter.getInt();
>         return TimeZone.findEnumeration(value);
>     }
>
>     public void setParameter(ParameterSetter setter, Object parameter) 
> throws SQLException {
>         if (parameter == null) {
>             setter.setNull(Types.INTEGER);
>         } else {
>             TimeZone param = (TimeZone) parameter;
>             setter.setInt(param.getDatabaseId());
>         }
>     }
>
>     public Object valueOf(String s){
>         return s;
>     }
>
> }
>
> ResultMap Working
>
> 	<resultMap id="simpleRequestResultMap" class="Request">
>         <result property="id" column="id"/>
>         ...
>         <result property="partner" column="partner"/>
>         <result property="partnerName" column="partner_name"/>
>         <result property="partnerEmail" column="partner_email"/>
>         <result property="partnerPhone" column="partner_phone"/>
>         <result property="contractNumber" column="contract_number"/>
>         <result property="timeZone" column="time_zone"/>
>         ...
>     </resultMap>
>
> ResultMap NOT Working! < Notice the order in regards to the time_zone 
> column >
>
> 	<resultMap id="simpleRequestResultMap" class="Request">
>         <result property="id" column="id"/>
>         ...
>         <result property="partner" column="partner"/>
>         <result property="partnerName" column="partner_name"/>
>         <result property="partnerEmail" column="partner_email"/>
>         <result property="partnerPhone" column="partner_phone"/>
> 		<result property="timeZone" column="time_zone"/>
>         <result property="contractNumber" column="contract_number"/>
>         ...
>     </resultMap>
>




Re: Bug with CTH and order of a ResultMap

Posted by Nathan Maves <Na...@Sun.COM>.
Anyone had a chance to look at this issue yet?

	Nathan

On Mar 3, 2005, at 9:46 AM, Nathan Maves wrote:

> Team,
>
> I know that this was not the intended way to use CTH but it works 99% 
> of the time!
>
> The 1% of the time that it fails is really strange.  It will only fail 
> if the column before it in the result map is null.  In the example 
> below I can get it to work if I move the line
>
> 	<result property="timeZone" column="time_zone"/>
>
> after a result that is NOT null.
>
> I am not sure why this is happening.  I thought that the order of the 
> result map meant nothing.
>
> Nathan
>
> SqlMapConfig
>
> 	<typeAlias alias="TimeZone" 
> type="giveservice.domain.definitions.TimeZone"/>
>
>     <typeHandler javaType="TimeZone" 
> callback="giveservice.dao.ibatis.typeHandler.TimeZoneCTH"/>
>
>
> CTH
> 	public class TimeZoneCTH implements TypeHandlerCallback {
>
>     public Object getResult(ResultGetter getter) throws SQLException {
>         if (getter.wasNull())
>             return null;
>         int value = getter.getInt();
>         return TimeZone.findEnumeration(value);
>     }
>
>     public void setParameter(ParameterSetter setter, Object parameter) 
> throws SQLException {
>         if (parameter == null) {
>             setter.setNull(Types.INTEGER);
>         } else {
>             TimeZone param = (TimeZone) parameter;
>             setter.setInt(param.getDatabaseId());
>         }
>     }
>
>     public Object valueOf(String s){
>         return s;
>     }
>
> }
>
> ResultMap Working
>
> 	<resultMap id="simpleRequestResultMap" class="Request">
>         <result property="id" column="id"/>
>         ...
>         <result property="partner" column="partner"/>
>         <result property="partnerName" column="partner_name"/>
>         <result property="partnerEmail" column="partner_email"/>
>         <result property="partnerPhone" column="partner_phone"/>
>         <result property="contractNumber" column="contract_number"/>
>         <result property="timeZone" column="time_zone"/>
>         ...
>     </resultMap>
>
> ResultMap NOT Working! < Notice the order in regards to the time_zone 
> column >
>
> 	<resultMap id="simpleRequestResultMap" class="Request">
>         <result property="id" column="id"/>
>         ...
>         <result property="partner" column="partner"/>
>         <result property="partnerName" column="partner_name"/>
>         <result property="partnerEmail" column="partner_email"/>
>         <result property="partnerPhone" column="partner_phone"/>
> 		<result property="timeZone" column="time_zone"/>
>         <result property="contractNumber" column="contract_number"/>
>         ...
>     </resultMap>
>