[ 
https://issues.apache.org/jira/browse/IBATIS-466?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12700236#action_12700236
 ] 

Kai Grabfelder commented on IBATIS-466:
---------------------------------------

here is what I would do:
- make sure the query returns the data sorted correctly (e.g. sort by the 
columns used for grouping). In the above example the sorting should look like 
ORDER BY person_id asc
- use a rowhandler, but no iBatis groupBy functionality
- do the groupBy functionality in your rowhandler, just you would do in plain 
old JDBC (continue to add albumbs to a person as long as the person_id does not 
change)

> Incorrect behaviour when combining RowHandler with groupBy
> ----------------------------------------------------------
>
>                 Key: IBATIS-466
>                 URL: https://issues.apache.org/jira/browse/IBATIS-466
>             Project: iBatis for Java
>          Issue Type: Bug
>          Components: SQL Maps
>    Affects Versions: 2.3.0
>            Reporter: William Shields
>
> Assuming:
> CREATE TABLE Person {
>   person_id NUMBER PRIMARY KEY,
>   name VARCHAR2(100)
> )
> CREATE TABLE Album (
>   album_id NUMBER PRIMARY KEY,
>   owner NUMBER REFERENCES (Person.person_id),
>   name VARCHAR2(100)
> )
> and
> public class Person {
>   private long personId;
>   private String name;
>   private List<Album> albums;
>   ...
> }
> public class Album {
>   private long albumId;
>   private long owner;
>   private String name;
>   ...
> }
> with query:
> <resultMap id="album" class="Abum">
>   <result property="albumId" column="ALBUM_ID"/>
>   <result property="owner" column="PERSON_ID"/>
>   <result property="name" column="ALBUM_NAME"/>
> </resultMap>
> <resultMap id="person" class="Person" groupBy="personId">
>   <result property="personId" column="PERSON_ID"/>
>   <result property="name" column="PERSON_NAME"/>
>   <result property="albums" resultMap="album"/>
> </resultMap>
> <select id="selectAlbums" resultMap="person">
>   SELECT person_id, p.name person_name, album_id, a.name album_name
>   FROM Person p, Album a
>   WHERE person_id = owner
> </select>
> with data:
> Person:
> 1 John
> 2 Mary
> Album:
> 10 1 "Bat Out Of Hell"
> 11 2 "The Wall"
> 12 2 "Eyes Open"
> 12 2 "White Ladder"
> Now, queryForList() works correctly.  Two Person objects are returned.  The 
> first (John) has 1 album, Mary has 3.  If instead you do:
> queryWithRowHandler("....selectAlbums", new RowHandler() {
>   public void handleRow(Object valueObject) {
>     Person p = (Person)valueObject;
>     System.out.println(p.getName() + " has " + p.getAlbums().size() + " 
> albums");
>   }
> }
> It displays 1 for each of the two rows.  The RowHandler is being called on 
> the first row and then it continues to add to the sub-list.  This is a real 
> problem if you want to process the fully loaded value object.  I've come up 
> with this workaround:
> public interface TypedRowHandler<T> {
>   void handle(T t);
> }
> public class CleverRowHandler<T> implements RowHandler {
>   TypedRowHandler<T> handler;
>   private T last;
>   public CleverRowHandler(TypedRowHandler<T> handler) {
>     this.handler = handler;
>   }
>   public void handleRow(Object valueObject) {
>     flush();
>     last = (T)valueObject;
>   }
>   public void flush() {
>     if (last != null) {
>       handler.handler(last);
>     }
>     last = null;
>   }
> }
> with DAO code:
> public void processPersons() {
>   CleverRowHandler<Person> rh = new CleverRowHandler<T>(new 
> TypedRowHandler<Person>() {
>     public void handle(Person p) {
>       // do whatever
>     }
>   };
>   try {
>     getSqlMapClientTemplate().queryWithRowHandler("....selectPersons", rh);
>   } finally {
>     rh.flush();
>   }
> }
> but that's rather messy.  I believe that the current behaviour is a bug and 
> introduces potential threading issues (in my case my row handler creates a 
> Runnable and submits it to a ExecutorService, which is a problem if ibatis is 
> still adding objects to the sub-list).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to