ibatis-user-cs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sean Blakemore" <sean.blakem...@gmail.com>
Subject Strange groupBy behaviour
Date Fri, 29 Jun 2007 17:24:42 GMT
Ok, I think I've struggled with this long enough to warrant posting here,
although I'm still not sure if this is a bug or me not understanding
something.. I think the only way I can explain this is by example so if
you'll bare with me. Below are some C# classes I'm mapping:

    public class Child
    {
        private Nullable<Int32> id = null;
        public virtual Nullable<Int32> Id
        {
            get { return id; }
            set { id = value; }
        }
        private String name;
        public String Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    public class Parent
    {
        public Parent()
        {
            marriageOne = new List<Child>();
            marriageTwo = new List<Child>();
        }
        private Nullable<Int32> id = null;
        public virtual Nullable<Int32> Id
        {
            get { return id; }
            set { id = value; }
        }
        private IList<Child> marriageOne;
        public IList<Child> MarriageOne
        {
            get { return marriageOne; }
        }
        private IList<Child> marriageTwo;
        public IList<Child> MarriageTwo
        {
            get { return marriageTwo; }
        }
    }

Note that there are two lists of type Child in the Parent class. The mapping
is as follows:

  <resultMaps>
    <resultMap id="parent" class="Parent" groupBy="id">
      <result property="id" column="Parent_ID"/>
      <result property="marriageOne" resultMapping="Test.marriageOneList"/>
      <result property="marriageTwo" resultMapping="Test.marriageTwoList"/>
    </resultMap>

    <resultMap id="marriageOneList" class="Child">
      <result property="id" column="MarriageOne_ID"/>
      <result property="name" column="MarriageOne_Name"/>
    </resultMap>
    <resultMap id="marriageTwoList" class="Child">
      <result property="id" column="MarriageTwo_ID"/>
      <result property="name" column="MarriageTwo_Name"/>
    </resultMap>
  </resultMaps>

Here beings the strangeness, if marriageOne has a single Child and
marriageTwo has two children (in the database), iBatis gives me two of the
same child in marriageOne. The inverse is true also, if marriageTwo has a
single Child and marriageOne has two, iBatis returns two identical children
in marriageTwo. This is easily solved, add a groupBy="id" on the two
resultMaps marriageOneList and marriageTwoList. The results from the
database looks like this:

Parent_ID    MarriageOne_ID    MarriageOne_Name    MarriageTwo_ID
MarriageTwo_Name

20        30        Child One        40        Child Two
20        30        Child One        50        Child Three

This works great untill we add a GrandParent:

    public class GrandParent
    {
        public GrandParent()
        {
            parents = new List<Parent>();
        }
        private Nullable<Int32> id = null;
        public virtual Nullable<Int32> Id
        {
            get { return id; }
            set { id = value; }
        }
        private IList<Parent> parents;
        public IList<Parent> Parents
        {
            get { return parents; }
        }
    }

    <resultMap id="grandParent" class="GrandParent" groupBy="id">
      <result property="id" column="GrandParent_ID"/>
      <result property="parents" resultMapping="Test.parent"/>
    </resultMap>

Now, let's say we have two parents, Parent1 and Parent2, Parent1 has one
Child in marriageOne and two in marriageTwo, and Parent2 has that same
single Child in marriageOne and nothing in marriageTwo (this is a pretty
messed up family :)). With groupBy="id" on the marriageOneList and
marriageTwoList, iBatis again returns the expected result for Parent1
however now Parent2 will show no children in marriageOne. The results from
the database look like this:

GrandParent_ID    Parent_ID    MarriageOne_ID    MarriageOne_Name
MarriageTwo_ID    MarriageTwo_Name

10        20        30        Child One        40        Child Two
10        20        30        Child One        50        Child Three
10        60        30        Child One        NULL        NULL

I hope that made some sense, it seems to me that the groupBy statements are
being evaluated in the wrong order leading to Child One being aggregated
into a single object. I'd be eternally grateful for any guidance on this,
I've wasted half a day isolating the problem and trying to find a
workaround.

Many thanks.

Mime
View raw message