I have seen a lot of good discussion around unit testing Hibernate-based DAOs when using lazy loading (for example: http://sourceforge.net/forum/forum.p...orum_id=250340). I wondered if anyone had encountered the same issues when using iBatis and has a similar solution?
DETAILS
----------
Spring 1.0.2, iBatis 2.0.5
I have a class that extends Spring's SqlMapClientDaoSupport and has the following method:
The Order class includes a java.util.List property for line items. The relevant extracts from the SQL Map file are as follows:Code:public Order loadOrder(String orderId) throws DataAccessException { return (Order) getSqlMapClientTemplate().queryForObject("loadOrder", orderId); }
Now, this all works fine when I run the web application: I see all Order and Line Item fields. In my JUnit class, I have the following code (DbUnit stuff omitted):Code:<sqlMap> <resultMap id="orderMap" class="domain.Order"> <result property="id" column="row_id"/> ...lots of other scalar fields... <result property="lineItems" column="row_id" select="findLineItemsByOrderId"/> </resultMap> <resultMap id="orderItemMap" class="domain.OrderLineItem"> <result property="id" column="row_id"/> ...lots of other scalar fields... </resultMap> <select id="loadOrder" resultMap="orderMap"> SELECT row_id, ...other columns... FROM order WHERE row_id = #value# </select> <select id="findLineItemsByOrderId" parameterClass="java.lang.String" resultMap="orderItemMap"> SELECT row_id, ...other columns... FROM order_item WHERE order_id = #value# </select> </sqlMap>
When I first attempt to read the value of the line items List property, I get the following stack trace:Code:protected DriverManagerDataSource m_dataSource; //Actually initialized in superclass protected SqlMapClient m_sqlMapClient; // Actually initialized in superclass private OrderDao m_dao; protected void setUp() throws Exception { m_dataSource = new SingleConnectionDataSource(); m_dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); m_dataSource.setUrl("jdbc:hsqldb:db-location"); m_dataSource.setUsername("sa"); m_dataSource.setPassword(""); m_sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(...); m_dao = new SqlMapOrderDao(); m_dao.setDataSource(m_dataSource); m_dao.setSqlMapClient(m_sqlMapClient); } public void testLoadOrder() { Order order = m_dao.loadOrder(orderId); System.out.println(order); // Exception is thrown here! ...assertions omitted for brevity... }
If I disable lazy-loading, the unit test runs just fine.java.lang.NullPointerException
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelega te.endTransaction(SqlMapExecutorDelegate.java:465)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.en dTransaction(SqlMapSessionImpl.java:134)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.end Transaction(SqlMapClientImpl.java:107)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelega te.autoEndTransaction(SqlMapExecutorDelegate.java: 515)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelega te.queryForList(SqlMapExecutorDelegate.java:381)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelega te.queryForList(SqlMapExecutorDelegate.java:359)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.qu eryForList(SqlMapSessionImpl.java:90)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.que ryForList(SqlMapClientImpl.java:65)
at com.ibatis.sqlmap.engine.mapping.result.loader.Res ultLoader.getResult(ResultLoader.java:65)
at com.ibatis.sqlmap.engine.mapping.result.loader.Laz yResultLoader.loadObject(LazyResultLoader.java:94)
at com.ibatis.sqlmap.engine.mapping.result.loader.Laz yResultLoader.invoke(LazyResultLoader.java:77)
at $Proxy0.hashCode(Unknown Source)
at java.util.HashMap.hash(HashMap.java:261)
at java.util.HashMap.containsKey(HashMap.java:339)
at java.util.HashSet.contains(HashSet.java:180)
at org.apache.commons.lang.builder.ReflectionToString Builder.isRegistered(ReflectionToStringBuilder.jav a:141)
at org.apache.commons.lang.builder.ToStringStyle.appe ndInternal(ToStringStyle.java:340)
at org.apache.commons.lang.builder.ToStringStyle.appe nd(ToStringStyle.java:314)
at org.apache.commons.lang.builder.ToStringBuilder.ap pend(ToStringBuilder.java:872)
at domain.Order.toString(Order.java:361)
...etc. etc....


Reply With Quote