Hi,
It seems that IBatis (or maybe cglib) doesn't fully support Java 1.5 generics.
Here is my use case (a somewhat deep hierarchy):
===== DOMAIN MODEL =====
//-----------------------------
public interface Persistable
{
public void setId(Integer id);
public Integer getId();
}
//-----------------------------
public abstract class AbstractPersistable
implements Persistable
{
private Integer id;
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
}
//-----------------------------
public interface Node<N extends Node> extends Persistable
{
public void setParent(N parent);
public N getParent();
...
}
//-----------------------------
public abstract class AbstractNode<N extends AbstractNode>
extends AbstractPersistable implements Node<N>
{
private N parent;
public N getParent()
{
return this.parent;
}
public void setParent(N parent)
{
this.parent = parent;
}
...
}
//-----------------------------
public class Category extends AbstractNode<Category>
{
... some other methods
}
===== DAOS CLASSES AND INTERFACES =====
//-----------------------------
public interface PersistableDAO<P extends Persistable> {
public P findById(Integer id);
}
//-----------------------------
public interface NodeDAO<N extends Node> extends PersistableDAO<N>
{
... some other methods
}
//-----------------------------
public abstract class AbstractIbatisAccess<D extends Persistable>
extends SqlMapDaoTemplate implements PersistableDAO<D>
{
public AbstractIbatisAccess(DaoManager manager)
{
super(manager);
}
public D findById(Integer id)
{
try
{
return (D) getSqlMapExecutor().queryForObject(getNamespace() +
".findById", id);
} catch (SQLException e)
{
throw new DaoException(e);
}
}
...
}
//-----------------------------
public abstract class AbstractNodeIbatisAccess<D extends Node<D>>
extends AbstractIbatisAccess<D> implements NodeDAO<D>
{
public AbstractNodeIbatisAccess(DaoManager manager)
{
super(manager);
}
... override some methods
}
//-----------------------------
public class CategoryIbatisAccess
extends AbstractNodeIbatisAccess<Category> implements CategoryDAO {
public CategoryIbatisAccess(DaoManager manager) {
super(manager);
}
@Override
protected String getNamespace() {
return "categories";
}
}
===== DAOS CONFIG =====
...
<dao interface="org.xenata.ads.dao.CategoryDAO"
implementation="org.xenata.ads.access.ibatis.CategoryIbatisAccess"/>
...
===== SQLMAP =====
<resultMap id="category" class="org.xenata.ads.domain.Category">
<result property="id" column="id"/>
<result property="parent" column="parent_id" select="categories.findById"/>
...
</resultMap>
<select id="findById"
parameterClass="int"
resultMap="category">
select id,
parent_id,
...
from categories
where id = #value#
</select>
=============================================
When doing:
CategoryDAO dao = daoManager.getDao(CategoryDAO.class);
Category category = dao.findById(1);
I get the Exception below. Any idea? Has anyone worked with generics and
iBatis?
I am under the impression that cglib doesn't know it has to enhance an actual
Category. Or is it something that could be solved in iBatis?
Thanks.
Oscar
===== EXCEPTION TRACE =====
Testcase: testFindById(org.xenata.ads.access.ibatis.CategoryIbatisAccessTest):
Caused an ERROR
null
com.ibatis.dao.client.DaoException
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in resources/ibatis/category.xml.
--- The error occurred while applying a result map.
--- Check the categories.category.
--- The error happened while setting a property on the result object.
--- Cause: com.ibatis.common.exception.NestedRuntimeException: Error setting
properties of '[EMAIL PROTECTED]'. Cause:
java.lang.ClassCastException:
org.xenata.ads.domain.Node$$EnhancerByCGLIB$$1e4f4b2f_2
Caused by: java.lang.ClassCastException:
org.xenata.ads.domain.Node$$EnhancerByCGLIB$$1e4f4b2f_2
Caused by: com.ibatis.common.exception.NestedRuntimeException: Error setting
properties of '[EMAIL PROTECTED]'. Cause:
java.lang.ClassCastException:
org.xenata.ads.domain.Node$$EnhancerByCGLIB$$1e4f4b2f_2
Caused by: java.lang.ClassCastException:
org.xenata.ads.domain.Node$$EnhancerByCGLIB$$1e4f4b2f_2
at
org.xenata.ads.access.ibatis.AbstractIbatisAccess.findById(AbstractIbatisAccess.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72)
at $Proxy3.findById(Unknown Source)
at
org.xenata.ads.access.ibatis.CategoryIbatisAccessTest.testFindById(CategoryIbatisAccessTest.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:
__________________________________
Do you Yahoo!?
Yahoo! Sports - Sign up for Fantasy Baseball.
http://baseball.fantasysports.yahoo.com/