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 Dragan Jotanovic <Dr...@DIOSPHERE.com> on 2008/07/17 15:12:27 UTC

Bug with complex property in result map?

Hi there,

I noticed that after upgrading to newer version of iBatis, some of the
functionality that used to work with iBatis 2.0.9 stopped working.

Namely, the problem occurred in case when there is complex property in
result map.

Here is the simple test case:

- Sql map:

 

  <resultMap id="resultA" class="A">

    <result property="id" column="ID"/>

    <result property="description" column="DESCRIPTION"/>

  </resultMap>

  

  <resultMap id="resultB" class="B">

    <result property="id" column="ID"/>

    <result property="a_id" column="A_ID"/>

    <result property="a" column="A_ID" select="getA"/>

  </resultMap>

 

  <select id="getAllB" resultMap="resultB">

    select * from TABLE_B

  </select>

  

  <select id="getA" resultMap="resultA">

    select * from TABLE_A

    where id=#value#

  </select>

 

- class A(id, description); class B (id, a_id, object A)

 

- TABLE_A(id, description){(1, rec 1), (2, rec 2)}

- TABLE_B(id, a_id){(1, 1), (1, null)}

 

As you can see, a_id field in TABLE_B is nullable. 

When you invoke queryForList("getAllB"), iBatis breaks with following
exception:

com.ibatis.common.jdbc.exception.NestedSQLException:   

--- The error occurred in Test.xml.  

--- The error occurred while applying a result map.  

--- Check the Test.resultB.  

--- Check the result mapping for the 'a' property.  

--- Cause: java.lang.NullPointerException

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryW
ithCallback(MappedStatement.java:204)

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryF
orList(MappedStatement.java:139)

      at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMap
ExecutorDelegate.java:567)

      at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMap
ExecutorDelegate.java:541)

      at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessi
onImpl.java:118)

      at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClient
Impl.java:94)

      at TestIbatis.main(TestIbatis.java:28)

Caused by: java.lang.NullPointerException

      at java.lang.Class.isAssignableFrom(Native Method)

      at
com.ibatis.sqlmap.engine.type.TypeHandlerFactory.getTypeHandler(TypeHand
lerFactory.java:143)

      at
com.ibatis.sqlmap.engine.type.TypeHandlerFactory.getTypeHandler(TypeHand
lerFactory.java:123)

      at
com.ibatis.sqlmap.engine.mapping.result.ResultMap.prepareBeanParameterOb
ject(ResultMap.java:591)

      at
com.ibatis.sqlmap.engine.mapping.result.ResultMap.getNestedSelectMapping
Value(ResultMap.java:475)

      at
com.ibatis.sqlmap.engine.mapping.result.ResultMap.getResults(ResultMap.j
ava:341)

      at
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:384)

      at
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(Sql
Executor.java:300)

      at
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:189)

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteQue
ry(MappedStatement.java:221)

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryW
ithCallback(MappedStatement.java:189)

      ... 6 more

 

What I would expect is that for those null values in database, null
value of property A in class B to be set.

This used to work in version 2.0.9, and was broken after version 2.2 I
think. I tried with latest 2.3.3 as well with the same result.

Is this a known issue, or maybe a feature? Is there some simple
workaround for the problem? I am aware that above solution is not
perfect (problem of N+1 selects), but we already implemented a lot of
queries this way and it would be time consuming to rewrite them all.

 

Dragan


Re: Bug with complex property in result map?

Posted by Clinton Begin <cl...@gmail.com>.
That's fixed in 2.3.3 (but not 2.3.1 or 2.3.2).

Double check your versions.  Line 143 in TypeHandlerFactory in 2.3.3 is a
comment... ;-)

Clinton

On Sun, Jul 20, 2008 at 11:57 AM, Dragan Jotanovic <
Dragan.Jotanovic@diosphere.com> wrote:

>  Has anyone noticed this bug? I can't believe that no one has stumbled
> upon this.
>
>
>
> Dragan
>
>
>
> *From:* Dragan Jotanovic [mailto:Dragan.Jotanovic@DIOSPHERE.com]
> *Sent:* Thursday, July 17, 2008 2:12 PM
> *To:* user-java@ibatis.apache.org
> *Subject:* Bug with complex property in result map?
>
>
>
> Hi there,
>
> I noticed that after upgrading to newer version of iBatis, some of the
> functionality that used to work with iBatis 2.0.9 stopped working.
>
> Namely, the problem occurred in case when there is complex property in
> result map.
>
> Here is the simple test case:
>
> - Sql map:
>
>
>
>   <resultMap id="resultA" class="A">
>
>     <result property="id" column="ID"/>
>
>     <result property="description" column="DESCRIPTION"/>
>
>   </resultMap>
>
>
>
>   <resultMap id="resultB" class="B">
>
>     <result property="id" column="ID"/>
>
>     <result property="a_id" column="A_ID"/>
>
>     <result property="a" column="A_ID" select="getA"/>
>
>   </resultMap>
>
>
>
>   <select id="getAllB" resultMap="resultB">
>
>     select * from TABLE_B
>
>   </select>
>
>
>
>   <select id="getA" resultMap="resultA">
>
>     select * from TABLE_A
>
>     where id=#value#
>
>   </select>
>
>
>
> - class A(id, description); class B (id, a_id, object A)
>
>
>
> - TABLE_A(id, description){(1, 'rec 1'), (2, 'rec 2')}
>
> - TABLE_B(id, a_id){(1, 1), (1, null)}
>
>
>
> As you can see, a_id field in TABLE_B is nullable.
>
> When you invoke queryForList("getAllB"), iBatis breaks with following
> exception:
>
> *com.ibatis.common.jdbc.exception.NestedSQLException*:
>
> --- The error occurred in Test.xml.
>
> --- The error occurred while applying a result map.
>
> --- Check the Test.resultB.
>
> --- Check the result mapping for the 'a' property.
>
> --- Cause: *java.lang.NullPointerException*
>
>       at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(
> *MappedStatement.java:204*)
>
>       at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryForList(
> *MappedStatement.java:139*)
>
>       at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
> *SqlMapExecutorDelegate.java:567*)
>
>       at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
> *SqlMapExecutorDelegate.java:541*)
>
>       at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(*
> SqlMapSessionImpl.java:118*)
>
>       at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(*
> SqlMapClientImpl.java:94*)
>
>       at TestIbatis.main(*TestIbatis.java:28*)
>
> Caused by: *java.lang.NullPointerException*
>
>       at java.lang.Class.isAssignableFrom(*Native Method*)
>
>       at com.ibatis.sqlmap.engine.type.TypeHandlerFactory.getTypeHandler(*
> TypeHandlerFactory.java:143*)
>
>       at com.ibatis.sqlmap.engine.type.TypeHandlerFactory.getTypeHandler(*
> TypeHandlerFactory.java:123*)
>
>       at
> com.ibatis.sqlmap.engine.mapping.result.ResultMap.prepareBeanParameterObject(
> *ResultMap.java:591*)
>
>       at
> com.ibatis.sqlmap.engine.mapping.result.ResultMap.getNestedSelectMappingValue(
> *ResultMap.java:475*)
>
>       at com.ibatis.sqlmap.engine.mapping.result.ResultMap.getResults(*
> ResultMap.java:341*)
>
>       at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(*
> SqlExecutor.java:384*)
>
>       at
> com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(*
> SqlExecutor.java:300*)
>
>       at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(*
> SqlExecutor.java:189*)
>
>       at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteQuery(
> *MappedStatement.java:221*)
>
>       at
> com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(
> *MappedStatement.java:189*)
>
>       ... 6 more
>
>
>
> What I would expect is that for those null values in database, value of
> property A in class B to be set to null.
>
> This used to work in version 2.0.9, and was broken after version 2.2 I
> think. I tried with latest 2.3.3 as well with the same result.
>
> Is this a known issue, or maybe a feature? Is there some simple workaround
> for the problem? I am aware that above solution is not perfect (problem of
> N+1 selects), but we already implemented a lot of queries this way and it
> would be time consuming to rewrite them all.
>
>
>
> Dragan
>

RE: Bug with complex property in result map?

Posted by Dragan Jotanovic <Dr...@DIOSPHERE.com>.
Has anyone noticed this bug? I can't believe that no one has stumbled
upon this.

 

Dragan

 

From: Dragan Jotanovic [mailto:Dragan.Jotanovic@DIOSPHERE.com] 
Sent: Thursday, July 17, 2008 2:12 PM
To: user-java@ibatis.apache.org
Subject: Bug with complex property in result map?

 

Hi there,

I noticed that after upgrading to newer version of iBatis, some of the
functionality that used to work with iBatis 2.0.9 stopped working.

Namely, the problem occurred in case when there is complex property in
result map.

Here is the simple test case:

- Sql map:

 

  <resultMap id="resultA" class="A">

    <result property="id" column="ID"/>

    <result property="description" column="DESCRIPTION"/>

  </resultMap>

  

  <resultMap id="resultB" class="B">

    <result property="id" column="ID"/>

    <result property="a_id" column="A_ID"/>

    <result property="a" column="A_ID" select="getA"/>

  </resultMap>

 

  <select id="getAllB" resultMap="resultB">

    select * from TABLE_B

  </select>

  

  <select id="getA" resultMap="resultA">

    select * from TABLE_A

    where id=#value#

  </select>

 

- class A(id, description); class B (id, a_id, object A)

 

- TABLE_A(id, description){(1, 'rec 1'), (2, 'rec 2')}

- TABLE_B(id, a_id){(1, 1), (1, null)}

 

As you can see, a_id field in TABLE_B is nullable. 

When you invoke queryForList("getAllB"), iBatis breaks with following
exception:

com.ibatis.common.jdbc.exception.NestedSQLException:   

--- The error occurred in Test.xml.  

--- The error occurred while applying a result map.  

--- Check the Test.resultB.  

--- Check the result mapping for the 'a' property.  

--- Cause: java.lang.NullPointerException

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryW
ithCallback(MappedStatement.java:204)

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryF
orList(MappedStatement.java:139)

      at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMap
ExecutorDelegate.java:567)

      at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMap
ExecutorDelegate.java:541)

      at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessi
onImpl.java:118)

      at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClient
Impl.java:94)

      at TestIbatis.main(TestIbatis.java:28)

Caused by: java.lang.NullPointerException

      at java.lang.Class.isAssignableFrom(Native Method)

      at
com.ibatis.sqlmap.engine.type.TypeHandlerFactory.getTypeHandler(TypeHand
lerFactory.java:143)

      at
com.ibatis.sqlmap.engine.type.TypeHandlerFactory.getTypeHandler(TypeHand
lerFactory.java:123)

      at
com.ibatis.sqlmap.engine.mapping.result.ResultMap.prepareBeanParameterOb
ject(ResultMap.java:591)

      at
com.ibatis.sqlmap.engine.mapping.result.ResultMap.getNestedSelectMapping
Value(ResultMap.java:475)

      at
com.ibatis.sqlmap.engine.mapping.result.ResultMap.getResults(ResultMap.j
ava:341)

      at
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:384)

      at
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(Sql
Executor.java:300)

      at
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:189)

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteQue
ry(MappedStatement.java:221)

      at
com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryW
ithCallback(MappedStatement.java:189)

      ... 6 more

 

What I would expect is that for those null values in database, value of
property A in class B to be set to null.

This used to work in version 2.0.9, and was broken after version 2.2 I
think. I tried with latest 2.3.3 as well with the same result.

Is this a known issue, or maybe a feature? Is there some simple
workaround for the problem? I am aware that above solution is not
perfect (problem of N+1 selects), but we already implemented a lot of
queries this way and it would be time consuming to rewrite them all.

 

Dragan