2010-03-15 10 views
1

J'ai la configuration configuration classiquecartographie des relations parent-enfant avec iBatis

public class Parent { 
    Integer id; 
    ... 
    // No generics 
    Collection someCollectionAttribute; 
    ... 
    public void setChildren(Collection c) { 
     ... 
    } 
} 

public class Child { 
    Integer id; 
    ... 
} 

et je suis en train de cartographier cela sur la table habituelle en utilisant iBatis (version 2.30 ... ne demandez pas).

create table parents (
    ID integer primary key 
    ... 
) 

create table children (
    ID integer primary key 
    PARENT_ID integer references parents(id) 
    ... 
) 

Mon fichier de mappage ressemble à ce

<resultMap id="ParentResult" groupBy="id"> 
    <result property="id" column="ID" /> 
    ... 
    <result property="children" resultMap="ChildResult" /> 
</resultMap> 

<resultMap id="ChildResult"> 
    <result property="id" column="ID" /> 
    <result property="parentId" column="PARENT_ID" /> 
    ... 
</result> 

<sql id="loadParent" resultMap="ParentResult"> 
    select P.ID as p1, ..., C.ID as c1, C.PARENT_ID as c2 ... 
    from parents P 
    join children C on (P.ID = C.PARENT_ID) 
    where P.ID = #id# 
    order by P.ID 
</sql> 

Faire la sqlMap.queryForObject("loadParent", new Integer(42)) habituelle d'abord provoqué une NullPointerException à l'intérieur du poseur setChildren qui est apparemment appelé avec un argument nul (mon mauvais). La correction du setter fonctionne très bien, mais les journaux montrent que setChildren est appelée une seule fois avant même d'exécuter une seule instruction SQL, toujours avec un argument null, donc je me demande ce qui se passe ici. Quelqu'un a des indices?

Répondre

1

Je suppose que le problème réside dans le fait que vos noms de colonne (vos alias spécifiés) dans le jeu de résultats ne correspondent pas aux mappages des cartes de résultat d'iBatis. Votre exemple semble incomplet, donc je ne peux pas dire exactement.

De toute façon, voici un exemple de travail complet correspondant à votre configuration (testé avec iBatis 2.3.0.677). Si vous comparez avec ce que vous avez peut-être, vous comprendrez où est le problème.

tables de base de données:

create table parents (
    ID integer primary key, 
    BLA VARCHAR(100) 
); 

insert into parents(id, bla) values 
(1, 'text1'), 
(2, 'text2'); 

create table children (
    ID integer primary key, 
    PARENT_ID integer references parents(id), 
    BLA_CHILD VARCHAR(100) 
); 

insert into children(id, parent_id, bla_child) values 
(10, 1, 'child for 1 1'), 
(11, 1, 'child for 1 2'), 

(12, 2, 'child for 2 1'), 
(13, 2, 'child for 2 2'), 
(14, 2, 'child for 2 3'), 
(15, 2, 'child for 2 4'); 

haricots:

package model.pack; 
import java.util.Collection; 
public class Parent { 
    private Integer id; 
    private String bla; 
    private Collection children; 

    public Collection getChildren() { 
     return children; 
    } 
    public void setChildren(Collection children) { 
     this.children = children; 
    } 
    public Integer getId() { 
     return id; 
    } 
    public void setId(Integer id) { 
     this.id = id; 
    } 
    public String getBla() { 
     return bla; 
    } 
    public void setBla(String bla) { 
     this.bla = bla; 
    } 
} 

package model.pack; 
public class Child { 
    private Integer id; 
    private Integer parentId; 
    private String bla; 

    public Integer getParentId() { 
     return parentId; 
    } 
    public void setParentId(Integer parentId) { 
     this.parentId = parentId; 
    } 
    public Integer getId() { 
     return id; 
    } 
    public void setId(Integer id) { 
     this.id = id; 
    } 
    public String getBla() { 
     return bla; 
    } 
    public void setBla(String bla) { 
     this.bla = bla; 
    } 
} 

mapping Sql:

<sqlMap> 
    <resultMap id="childResult" class="model.pack.Child"> 
     <result property="id" column="childId" /> 
     <result property="parentId" column="childParentId" /> 
     <result property="bla" column="childBla" /> 
    </resultMap> 

    <resultMap id="parentResult" class="model.pack.Parent" groupBy="id"> 
     <result property="id" column="parentId" /> 
     <result property="bla" column="parentBla" /> 
     <result property="children" resultMap="childResult" /> 
    </resultMap> 

    <select id="loadParent" parameterClass="int" resultMap="parentResult"> 
     select p.id as parentId, p.bla as parentBla, c.id as childId, 
     c.bla_child as childBla, c.parent_id as childParentId 
     from parents p left outer join children c 
     on c.parent_id = p.id 
     where p.id = #id# 
     order by p.id 
    </select> 
</sqlMap> 

Si vous exécutez alors sqlMap.queryForObject("loadParent", new Integer(1)) ou sqlMap.queryForObject("loadParent", new Integer(2)) vous devriez obtenir un objet parent avec deux enfants et un parent avec quatre enfants respectivement.

+0

Je reçois Il n'y a pas de carte nommé result « childResult » toute aide appréciée. –

0

Je crois que la clé est que dans le resultMap, et doit être utilisé au lieu de <result>.

<resultMap id="ParentResult" groupBy="id"> 
    <result property="id" column="ID" /> 
    ... 
    <collection property="children" javaType="ArrayList" ofType="Child" resultMap="ChildResult" /> 
</resultMap> 

<resultMap id="ChildResult"> 
    <result property="id" column="ID" /> 
    <association property="parentId" foreignColumn="PARENT_ID" resultMap="ParentResult" /> 
    ... 
</result>