Menu

Mapping inheritance

Help
seb
2005-08-24
2013-05-02
  • seb

    seb - 2005-08-24

    Hi guys ! (oh no, he's back again !!)

    3 points today :)

    1/ Wildcard property

    In my dozerBeanMapping.xml, wildcard is set to false.
    I have an object A with a field named list which is a List.
    I have an object B with a field named list which is a List.
    My mapping is :

    <mapping>
    <classA>wildcard.A</classA>
    <classB>wildcard.B</classB>
    </mapping>

    I have a A instance with 2 String in list field.
    When i map A to B, the B.list field also contains 2 String ! To avoid this, i have to add wildcard="false" as a property for the current mapping ...

    2/ Inheritance

    Case 1 :
    --------
    Look at my class diagram : http://img6.imageshack.us/img6/6892/050824inheritance6sp.jpg
    I have 2 mappings : one between SuperClass and ClassPrime, and one between SubClass and ClassPrime.
    When i try to map a SubClass object fully loaded in a ClassPrime empty one, getSuperAttribute2() always gives me null.

    Case 2 :
    --------
    Let's make a few changes : http://img208.imageshack.us/img208/1579/050824inheritance27aw.jpg
    My mappings are now between SuperClass and SuperClassPrime, and between SubClass and SubClassPrime.
    The previous mapping test gives me the same result :(

    3/ List and inheritance

    Here's a more complex problem. Look at the class diagram : http://img364.imageshack.us/img364/9441/050824listandinheritance3ne.jpg
    So A contains a List field (roleB) of B objects, maybe B1 or B2.
    APrime contains a List field (roleB) of BPrime objects, maybe BPrime1 or BPrime2.

    My mapping between A and APrime looks like (wilcard turned off) :

    <mapping>
    <classA>A</classA>
    <classB>APrime</class>
    <field relationshipType="non-cumulative">
      <A>roleB</A>
      <B>roleB</B>
      <sourceTypeHint>B</sourceTypeHint>
      <destinationTypeHint>BPrime</destinationTypeHint>
    </field>
    </mapping>

    Mappings between B and BPrime, between B1 and BPrime1, and between B2 and BPrime2 are also made.

    Suppose i have a A object. A.roleB contains one B1 object and one B2 object.
    When i map my A object to a APrime one, and when i look into APrime.roleB, it contains only BPrime-type objects :'(

    So here's a suggestion to complete your great product :

    What do you think about introducing a new property for mapping tag : inherits
    My mapping will be :

    <mapping name="m1">
    <classA>B</classA>
    <classB>BPrime</classB>
    <mapping>

    <mapping inherits="m1">
    <classA>B1</classA>
    <classB>BPrime1</classB>
    <field>
      <A>b1</A>
      <B>b1</B>
    </field>
    <mapping>

    <mapping inherits="m1">
    <classA>B2</classA>
    <classB>BPrime2</classB>
    <field>
      <A>b2</A>
      <B>b2</B>
    </field>
    <mapping>

    <!-- mapping between A and APrime is untouched -->

    When dozer is loaded, you can easily (yes you can ;-) ) find all inherited children mapping for each named-mapping. Then, when you iterate on A.roleB, you 'just' have to use the relevant mapping :D
    I think the inheritance 'problem' (2/) can be resolved this way.

    Furthermore, this behaviour can be extended to allow multiple inheritance.
    Here's another (and my last ;-) ) class diagram : http://img297.imageshack.us/img297/4106/050824multipleinheritance5md.jpg
    I hope it illustrates mapping inheritance advantages :)

    Ready for the next release ? ;-)

    Bye
    Seb

     
    • Ben Sullins

      Ben Sullins - 2005-08-24

      We could not hope for a better user.  Thanks Seb.

       
    • Franz Garsombke

      Franz Garsombke - 2005-08-24

      Every Open Source project wishes they had someone with the bug finding abilities of Seb. Once again we appreciate your finely honed investigative skills and will fix all of these for the 1.5 release.

      Thanks Seb.

      Franz

      BTW - You got these Ben?

       
    • Ben Sullins

      Ben Sullins - 2005-08-24

      yes

       
    • Ben Sullins

      Ben Sullins - 2005-08-24

      Seb,

      Your point #1 seems to work as designed, not sure what you are referring to here. 

      I will start the other points today.

      Ben

       
      • Richard Lemesle

        Richard Lemesle - 2005-08-24

        Hi,

        As Seb said, its dozerBeanMapping.xml contains wildcard set to false.

        So, logically, none of the attributes of A will be mapped to B. But list attributes of A ARE mapped to B ;-)

        If we set the wildcard property to false in the mapping itself (<mapping wildcard="false">...), its ok : none of the attributes of A are mapped to B...

        So, the wildcard default value is not used for list atrtibutes mapping (it seems to be a bug ;-)

        Richard.

         
        • Franz Garsombke

          Franz Garsombke - 2005-08-24

          Nice find guys. This will be fixed for the 1.5 release.

          Thanks,

          Franz

           
    • seb

      seb - 2005-08-31

      Hi guys !

      Well, this morning i was enjoyed to see the 1.5 release. But, i don't want to break the habits, so here are my conclusions :

      Fixed a global wildcard bug --> tested and approved. Enjoy !

      Addressed adding vs. updating List. We were not truly updating the list --> well, updating is now working, but it seems that "non-cumulative" value for relationshipType doesn't work anymore :-(

      And i saw nothing about mappig inheritance :'(
      Still in the roadmap ?

      Bye
      Seb, waiting for the 1.5.1 release ;-)

       
      • Franz Garsombke

        Franz Garsombke - 2005-08-31

        Hey Seb -

        Good morning to you :). I opened a defect against mapping inheritance. Ben is working on that for 1.5.1. He has 2 of your 3 UML diagrams done. The third one is pretty hard he said.

        As far as non-cumulative...here is my unit test and it seems to work:
        TestReferenceObject tro = new TestReferenceObject();
        TestReferenceFoo foo2 = new TestReferenceFoo();
        foo2.setA("a");
        foo2.setB(null);
        foo2.setC("c");
        tro.setArrayToArrayNoncumulative(new Object[] { foo2 });
        // clone for our assert
        TestReferenceObject toClone = (TestReferenceObject) SerializationUtils.clone(tro);
        // map to prime
        TestReferencePrimeObject trop = (TestReferencePrimeObject) Mapper.map(tro, TestReferencePrimeObject.class);
        // change 'b' value on fooPrime
        TestReferenceFooPrime fooPrime2 = (TestReferenceFooPrime) trop.getArrayToArrayNoncumulative()[0];
            fooPrime2.setB("b");
        // map by reference back to original
        Mapper.map(trop, tro);
        // make sure we didn't lose the initial value 'c' set
        assertEquals("c", ((TestReferenceFoo) tro.getArrayToArrayNoncumulative()[0]).getC());
        // compare cloned and original - if non-cumulative did not work this should fail since we would have two objects in the object[] vs. only the one we started with
        assertEquals(toClone, tro);

        Thoughts?

         
        • Richard Lemesle

          Richard Lemesle - 2005-09-08

          Hi,

          I see nothing in 1.5.1 release notes about mapping inheritance (we don't have made any tests on that yet).

          Do these updates have been merged in this release ?

          Thanks,

          Richard.

           
          • Franz Garsombke

            Franz Garsombke - 2005-09-08

            Hey Richard -

            We are still working on those. I didn't want to put that in until it is fully tested. We should have them entirely done in a few days. I will let you know when we finish that. A little more complicated than we thought...

            thanks for asking.

            franz

             
    • Franz Garsombke

      Franz Garsombke - 2005-09-09

      So....

      I have the first two scenarios working. Basically, the fix was just to walk up the source classes' superclasses and see if we have any mappings with the destintation class OR its superclasses. That one was pretty easy. The bug was that we only checked the source classes' superclass to the destination classes' superclass and nothing in between.

      The third scenario seems unrelated in that it has more to do with storing different object types in a Collection, vs. a pure 'inheritance' problem since that has been solved above. I don't know if I want to put mapping hierarchy into Dozer and start naming our maps. I can see a pandora's box with this.

      How about if every object we find in a Collection we look into our bag of Class Maps and see if any of them have the source object and a mapping to another class?. If we do find it then we map accordingly unless we have a destination hint which makes life easier. If we have more than one mapping to the source object then our only choice is not to map since we can not determine which mapping to choose, and I don't want to be responsible for those permutations.

      Thoughts?

       
      • Richard Lemesle

        Richard Lemesle - 2005-09-09

        Inheritance of mappings would be useful but hard to implement and also hard to use.

        I understand you don't want to go this way.

        I'm ok with the search of a mapping between B1 (third example of Seb) and something else. But you can make a more precise search of a mapping between B1 and a subtype of  BPrime.

        An other idea was to use multiple classes in source and destination type hint :
        <A>roleB</A>
        <B>roleBPrime</B>
        <sourceTypeHint>B,B1,B2</sourceTypeHint>
        <destinationTypeHint>BPrime,BPrime1,BPrime2</destinationTypeHint>

        If roleB is an instance of B it is map to BPrime,
        If roleB is an instance if B1, it is map to BPrime1,
        If roleB is an instance if B2, it is map to BPrime2

        The Dozer user can then define precisely his mappings...

         
        • Franz Garsombke

          Franz Garsombke - 2005-09-09

          Richard -

          So are you saying there is a one-to-one relationship (and in correct order) of the multiple hints you have to add?

          For example, I must know that since source hint B is first in the hint listing, and dest hint BPrime is first, then map those?

           
          • Richard Lemesle

            Richard Lemesle - 2005-09-10

            That's it.

            If I don't have mapping inheritance, I must explicitly give to Dozer all the possible mappings between an instance of B (or subtype of B) and and instance of  BPrime (or subtype of BPrime) for each relationship where B is mapped to BPrime.

            Mapping inheritance as we though it would be used to state that :

            <mapping id="1"
            <classA>B</classA>
            <classB>BPrime</classB>
            </mapping>

            <mapping id="2" extends="1">
            <classA>B1</classA>
            <classB>BPrime1</classB>
            </mapping>

            <mapping id="3" extends="1">
            <classA>B1</classA>
            <classB>BPrime1</classB>
            </mapping>

            And why not :

            <mapping id="4" extends="2">
            <classA>B11</classA>
            <classB>BPrime11</classB>
            </mapping>

            So the list of hints and its order can be found using these inheritance relationships.

            source hints = B11,B1,B2,B
            destination hints = BPrime11, BPrime1, BPrime2, BPrime.

             
            • Franz Garsombke

              Franz Garsombke - 2005-09-10

              Sounds reasonable. I will put that functionality in for 1.5.2.

               
    • Ching Chew

      Ching Chew - 2006-03-13

      Hi all,

      Sorry to dig up a potentially old thread.

      I was searching for a way to reuse an existing mapping on 2 classes that are exactly the same except for its package names, i.e.

      Already have mapping for A->B
      Want to have mapping for A->C where B and C have exactly the same attributes and I want it to be mapped the same way as A->B

      I looked around the support forums and thought this mapping inheritance would do the trick. However, looking at the dtd, I cannot find out the attributes needed to tell mapping A->C to use the A->B mapping.

      Thanks in advance for any help.

      Cheers!
      Ching

       
      • Franz Garsombke

        Franz Garsombke - 2006-03-14

        Have you checked out our inheritance documentation?

        http://dozer.sourceforge.net/documentation/baseattributes.html

        Please let me know if you have any questions.

        Thanks,

        Franz

         
        • Ching Chew

          Ching Chew - 2006-03-14

          Hi Franz,

          Thanks for the quick reply!

          I had a look around the doco previously and after reviewing the link that you sent through, I will rephrase my question:

          The 2 classes B and C are exactly the same class but not related in any sort of class hierarchy.

          Example, assuming we already have the following mapping between A->B:

          <mapping>
          <classA>A</classA>
          <classB>B</class>
          <field>
          <A>fieldA</A>
          <B>fieldB</B>
          </field>
          </mapping>

          Class C comes along and I want to map A->C according to:

          <mapping>
          <classA>A</classA>
          <classB>C</class>
          <field>
          <A>fieldA</A>
          <B>fieldB</B>
          </field>
          </mapping>

          Notice that class C also contains fieldB which is the same as fieldB in class B. Is there any way to tell Dozer to use the first mapping when mapping A->C even though C is not related in any way to B in terms of class hierarchy?

          The situation is that we have some generated code which unfortunately results in exactly the same class (X) being placed once in packageY and another time in packageZ where packageY.X and packageZ.X are exactly the same except for the package location.

          Cheers!
          Ching

           
          • Franz Garsombke

            Franz Garsombke - 2006-03-14

            Ahh....We do not have any support for that at this time. Interesting use case...copy/paste is the only option I see... :(

            Franz

             
    • Ching Chew

      Ching Chew - 2006-03-15

      Thanks Franz, I was afraid of that =(

      I will do the copy/paste reuse method for the time being - is this a feature that would interest others enough to have it be added to the roadmap?

      Cheers!
      Ching

       
      • Franz Garsombke

        Franz Garsombke - 2006-03-15

        We haven't had any other requests quite like that. The use case sounds pretty unique and I don't think we can add that to our roadmap... :(

        thanks for looking.

        franz

         

Log in to post a comment.