ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Niels Beekman" <n.beek...@wis.nl>
Subject RE: abstract property
Date Thu, 13 Sep 2007 15:40:23 GMT
If you study the exception in detail: Error instantiating collection
property for mapping 'myBar', you can see that iBATIS tries to
instantiate a collection. This is because you are using the resultMap
attribute to instantiate a non-collection property. I guess this is
unsupported, but I'm not sure about it. You could use the following
nested properties syntax:

<result property="myBar.barString" column="bar"/>

Maybe one of the iBATIS developers could comment on this one...

Niels

-----Original Message-----
From: Kenny Pearce [mailto:kenny.pearce@hxti.com] 
Sent: donderdag 13 september 2007 15:44
To: user-java@ibatis.apache.org
Subject: Re: abstract property

Alright, this is pretty long, but I've developed a basic case for the 
problem I'm having, and all the files, output, etc. are copied below. 
Maybe you can explain what I'm doing wrong.

=============== table create statement =====================
create table my_table (foo varchar(20), bar varchar(20), sub_bar 
varchar(20));

=============== insert statement ====================
insert into my_table values ('foo', 'bar', 'sub_bar');

=============== config.properties ==================
JDBC.Driver=com.mysql.jdbc.Driver
JDBC.ConnectionURL=jdbc:mysql://localhost:3306/ibatis_test
JDBC.Username=root
JDBC.Password=root

=============== config.xml ================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
    PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <properties resource="sqlmapconfig/config.properties"/>

       <transactionManager type="JDBC">
       <dataSource type="SIMPLE">
          <property name="JDBC.Driver"         value="${JDBC.Driver}" 
      />
          <property name="JDBC.ConnectionURL" 
value="${JDBC.ConnectionURL}" />
          <property name="JDBC.Username"       value="${JDBC.Username}" 
      />
          <property name="JDBC.Password"       value="${JDBC.Password}" 
      />
       </dataSource>
    </transactionManager>

    <sqlMap resource="sqlmapconfig/Foo.xml"/>
</sqlMapConfig>

================ Foo.xml ================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
     PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
     "http://www.ibatis.com/dtd/sql-map-2.dtd">


<sqlMap namespace="Foo">
	<resultMap class="Foo" id="fooResultMap">
		<result property="fooString" column="foo"/>
		<result property="myBar" resultMap="Foo.barResultMap"/>
	</resultMap>
	<resultMap class="SubBar" id="barResultMap">
		<result property="barString" column="bar"/>
		<result property="subBarString" column="sub_bar"/>
	</resultMap>
	
	<select id="fooSelect" parameterClass="string" resultClass="Foo"
			resultMap="fooResultMap">
		SELECT foo, bar, sub_bar from my_table WHERE foo =
#value#
	</select>
</sqlMap>

========================== Foo.java ========================
public class Foo {
	private String fooString;
	private Bar myBar;
	
	public String getFooString() {
		return fooString;
	}
	public void setFooString(String fooString) {
		this.fooString = fooString;
	}
	public Bar getMyBar() {
		return myBar;
	}
	public void setMyBar(Bar myBar) {
		this.myBar = myBar;
	}
}

===================== Bar.java ====================
public abstract class Bar {
	private String barString;

	public String getBarString() {
		return barString;
	}

	public void setBarString(String barString) {
		this.barString = barString;
	}
}

=================== SubBar.java =======================
public class SubBar extends Bar {
	private String subBarString;

	public String getSubBarString() {
		return subBarString;
	}

	public void setSubBarString(String subBarString) {
		this.subBarString = subBarString;
	}
}

==================== SQLTest.java ================
import java.io.InputStreamReader;
import java.io.Reader;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;


public class SQLTest {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SqlMapClient sql = null;
		try
		{
			Reader reader = new 
InputStreamReader(SQLTest.class.getResourceAsStream("/sqlmapconfig/confi
g.xml"));
			sql =
SqlMapClientBuilder.buildSqlMapClient(reader);
		}
		catch (Throwable t)
		{
			t.printStackTrace();
			System.exit(1);
		}
		
		Foo myFoo = null;
		try{
			myFoo = (Foo)sql.queryForObject("fooSelect",
"foo");
		}catch(Throwable t){
			t.printStackTrace();
			System.exit(2);
		}
		
		System.out.println(myFoo.getFooString() + " - " + 
myFoo.getMyBar().getBarString()
				+ " - " +
((SubBar)myFoo.getMyBar()).getSubBarString());
	}
}

=============================================================

Executing SQLTest results in the following being printed to stderr:

com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in sqlmapconfig/Foo.xml.
--- The error occurred while applying a result map.
--- Check the Foo.fooResultMap.
--- The error happened while setting a property on the result object.
--- Cause: com.ibatis.sqlmap.client.SqlMapException: Error instantiating

collection property for mapping 'myBar'.  Cause: 
java.lang.InstantiationException
Caused by: java.lang.InstantiationException
Caused by: com.ibatis.sqlmap.client.SqlMapException: Error instantiating

collection property for mapping 'myBar'.  Cause: 
java.lang.InstantiationException
Caused by: java.lang.InstantiationException
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
WithCallback(GeneralStatement.java:188)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
ForObject(GeneralStatement.java:104)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:561)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:536)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSes
sionImpl.java:93)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClie
ntImpl.java:70)
	at SQLTest.main(SQLTest.java:27)
Caused by: com.ibatis.sqlmap.client.SqlMapException: Error instantiating

collection property for mapping 'myBar'.  Cause: 
java.lang.InstantiationException
Caused by: java.lang.InstantiationException
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:397)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResult
Map(BasicResultMap.java:369)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectVa
lues(BasicResultMap.java:355)
	at 
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResu
ltObject(RowHandlerCallback.java:63)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:395)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:185)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQu
ery(GeneralStatement.java:205)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
WithCallback(GeneralStatement.java:173)
	... 6 more
Caused by: java.lang.InstantiationException
	at 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(In
stantiationExceptionConstructorAccessorImpl.java:30)
	at
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:395)
	... 13 more

Caused by:
com.ibatis.sqlmap.client.SqlMapException: Error instantiating collection

property for mapping 'myBar'.  Cause: java.lang.InstantiationException
Caused by: java.lang.InstantiationException
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:397)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResult
Map(BasicResultMap.java:369)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectVa
lues(BasicResultMap.java:355)
	at 
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResu
ltObject(RowHandlerCallback.java:63)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:395)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:185)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQu
ery(GeneralStatement.java:205)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
WithCallback(GeneralStatement.java:173)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
ForObject(GeneralStatement.java:104)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:561)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:536)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSes
sionImpl.java:93)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClie
ntImpl.java:70)
	at SQLTest.main(SQLTest.java:27)
Caused by: java.lang.InstantiationException
	at 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(In
stantiationExceptionConstructorAccessorImpl.java:30)
	at
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:395)
	... 13 more

Caused by:
java.lang.InstantiationException
	at 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(In
stantiationExceptionConstructorAccessorImpl.java:30)
	at
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:395)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResult
Map(BasicResultMap.java:369)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectVa
lues(BasicResultMap.java:355)
	at 
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResu
ltObject(RowHandlerCallback.java:63)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:395)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:185)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQu
ery(GeneralStatement.java:205)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
WithCallback(GeneralStatement.java:173)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
ForObject(GeneralStatement.java:104)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:561)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:536)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSes
sionImpl.java:93)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClie
ntImpl.java:70)
	at SQLTest.main(SQLTest.java:27)

Caused by:
com.ibatis.sqlmap.client.SqlMapException: Error instantiating collection

property for mapping 'myBar'.  Cause: java.lang.InstantiationException
Caused by: java.lang.InstantiationException
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:397)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResult
Map(BasicResultMap.java:369)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectVa
lues(BasicResultMap.java:355)
	at 
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResu
ltObject(RowHandlerCallback.java:63)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:395)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:185)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQu
ery(GeneralStatement.java:205)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
WithCallback(GeneralStatement.java:173)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
ForObject(GeneralStatement.java:104)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:561)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:536)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSes
sionImpl.java:93)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClie
ntImpl.java:70)
	at SQLTest.main(SQLTest.java:27)
Caused by: java.lang.InstantiationException
	at 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(In
stantiationExceptionConstructorAccessorImpl.java:30)
	at
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:395)
	... 13 more

Caused by:
java.lang.InstantiationException
	at 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(In
stantiationExceptionConstructorAccessorImpl.java:30)
	at
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:395)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResult
Map(BasicResultMap.java:369)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectVa
lues(BasicResultMap.java:355)
	at 
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResu
ltObject(RowHandlerCallback.java:63)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:395)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:185)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQu
ery(GeneralStatement.java:205)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
WithCallback(GeneralStatement.java:173)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
ForObject(GeneralStatement.java:104)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:561)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:536)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSes
sionImpl.java:93)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClie
ntImpl.java:70)
	at SQLTest.main(SQLTest.java:27)

Caused by:
java.lang.InstantiationException
	at 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(In
stantiationExceptionConstructorAccessorImpl.java:30)
	at
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setNestedResultMa
ppingValue(BasicResultMap.java:395)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResult
Map(BasicResultMap.java:369)
	at 
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectVa
lues(BasicResultMap.java:355)
	at 
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResu
ltObject(RowHandlerCallback.java:63)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor
.java:395)
	at 
com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.
java:185)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQu
ery(GeneralStatement.java:205)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
WithCallback(GeneralStatement.java:173)
	at 
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQuery
ForObject(GeneralStatement.java:104)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:561)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlM
apExecutorDelegate.java:536)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSes
sionImpl.java:93)
	at 
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClie
ntImpl.java:70)
	at SQLTest.main(SQLTest.java:27)


Niels Beekman wrote:
> How could iBATIS throw an InstantiationException when you're not even
> telling it the name of your abstract class? Please post the full
> exception stacktrace and your result maps.
> 
> Niels
> 
> -----Original Message-----
> From: Kenny Pearce [mailto:kenny.pearce@hxti.com] 
> Sent: woensdag 12 september 2007 20:46
> To: user-java@ibatis.apache.org
> Subject: abstract property
> 
> Hello,	
> 	I am trying to use iBatis in a case where I have an object
> hierarchy 
> like the following:
> 
> class Foo{
>     String fooString;
>     Bar myBar;
>     //getters and setters omitted
> }
> 
> abstract class Bar{
>     String barString;
>     //getters and setters omitted
> }
> 
> class SubBar extends Bar{
>     String subBarString;
>     //getters and setters omitted
> }
> 
> I would like to be able to do this:
> 
> <resultMap id="fooResultMap" class="Foo">
>     <result property="fooString" column="foo"/>
>     <result property="myBar" resultMap="barResultMap"/>
> </resultMap>
> 
> <resultMap id="barResultMap" class="SubBar">
>     <result property="barString" column="bar"/>
>     <result proprty="subBarString" column="sub_bar"/>
> </resultMap>
> 
> <select id="fooSelect" parameterClass="string" resultClass="Foo" 
> resultMap="fooResultMap">
>     SELECT foo, bar, sub_bar FROM table WHERE foo = #value#
> </select>
> 
> But that gives an InstantiationException (despite the fact that the 
> barResultMap has the class SubBar, which is concrete, specified). Next
I
> 
> tried using a discriminator and making a separate barResultMap and 
> subBarResultMap (where subBarResultMap extends barResultMap) with 
> <subMap value="*" ...> on a column that is never null (I'm not sure if

> wildcard is supported - I couldn't find discriminator in the docs, but

> it's not listed on the undocumented features page). That still threw
an 
> exception. Next, I changed the select statement to (the equivalent
of):
> 
>     SELECT foo, bar, sub_bar, 1 as use_submap FROM table WHERE foo =
> #value#
> 
> and used:
> 
> <discriminator column="use_submap" javaType="int">
> 	<subMap value="1" resultMap="subBarResultMap"/>
> </discriminator>
> 
> But no go there either.
> 
> Is there any way to do this, short of creating a custom object
factory?
> 
> 	Thanks,
> 

-- 
Kenny Pearce
Hx Technologies

Mime
View raw message