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/config.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.executeQueryWithCallback(GeneralStatement.java:188)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.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.setNestedResultMappingValue(BasicResultMap.java:397)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResultMap(BasicResultMap.java:369)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectValues(BasicResultMap.java:355)
at
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(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.sqlExecuteQuery(GeneralStatement.java:205)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
... 6 more
Caused by: java.lang.InstantiationException
at
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.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.setNestedResultMappingValue(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.setNestedResultMappingValue(BasicResultMap.java:397)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResultMap(BasicResultMap.java:369)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectValues(BasicResultMap.java:355)
at
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(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.sqlExecuteQuery(GeneralStatement.java:205)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:70)
at SQLTest.main(SQLTest.java:27)
Caused by: java.lang.InstantiationException
at
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.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.setNestedResultMappingValue(BasicResultMap.java:395)
... 13 more
Caused by:
java.lang.InstantiationException
at
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.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.setNestedResultMappingValue(BasicResultMap.java:395)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResultMap(BasicResultMap.java:369)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectValues(BasicResultMap.java:355)
at
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(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.sqlExecuteQuery(GeneralStatement.java:205)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.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.setNestedResultMappingValue(BasicResultMap.java:397)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResultMap(BasicResultMap.java:369)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectValues(BasicResultMap.java:355)
at
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(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.sqlExecuteQuery(GeneralStatement.java:205)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:70)
at SQLTest.main(SQLTest.java:27)
Caused by: java.lang.InstantiationException
at
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.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.setNestedResultMappingValue(BasicResultMap.java:395)
... 13 more
Caused by:
java.lang.InstantiationException
at
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.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.setNestedResultMappingValue(BasicResultMap.java:395)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResultMap(BasicResultMap.java:369)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectValues(BasicResultMap.java:355)
at
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(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.sqlExecuteQuery(GeneralStatement.java:205)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:70)
at SQLTest.main(SQLTest.java:27)
Caused by:
java.lang.InstantiationException
at
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.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.setNestedResultMappingValue(BasicResultMap.java:395)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.applyNestedResultMap(BasicResultMap.java:369)
at
com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectValues(BasicResultMap.java:355)
at
com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(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.sqlExecuteQuery(GeneralStatement.java:205)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
at
com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.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:[EMAIL PROTECTED]
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