#47 Inheritance mapping not working correctly

closed
None
7
2007-05-21
2006-05-11
No

Does not function properly when the subclass mapping
(s) arent explicit. Problem appears to be in
determineClassMap. Logic walks inheritance tree prior
to using default mapping of top level. Thus, the
super class mapping and none of the subclass attr's
are mapped. A unit test was submitted that reproduces
the problem. Those files are attached.

Discussion

  • Matt Tierney

    Matt Tierney - 2006-05-11
     
  • Matt Tierney

    Matt Tierney - 2006-05-11
     
  • Matt Tierney

    Matt Tierney - 2006-05-11
     
  • Matt Tierney

    Matt Tierney - 2006-05-11
     
  • Matt Tierney

    Matt Tierney - 2006-05-11

    Logged In: YES
    user_id=1236069

    Unit tests.....

    public void testKM1() {
    SomeVo request = new SomeVo();
    request.setUserName("yo");
    request.setAge("2");
    request.setColor("blue");

    MapperIF mapper = getNewMapper(new String[]
    {"kmmapping.xml"});

    Super afterMapping = (Super) mapper.map(request,
    Super.class);

    assertNotNull("login name should not be null",
    afterMapping.getLoginName());
    assertNotNull("age should not be null",
    afterMapping.getAge());
    assertEquals("should map SuperClass.name to
    SubClassPrime userName.",request.getUserName(),
    afterMapping.getLoginName());
    assertEquals(request.getAge(), afterMapping.getAge());
    }

    public void testKM2() {
    Sub request = new Sub();
    request.setAge("2");
    request.setColor("blue");
    request.setLoginName("fred");

    MapperIF mapper = getNewMapper(new String[]
    {"kmmapping.xml"});

    SomeVo afterMapping = (SomeVo) mapper.map(request,
    SomeVo.class);

    assertNotNull("un should not be null",
    afterMapping.getUserName());
    assertNotNull("color should not be null",
    afterMapping.getColor());
    assertNotNull("age should not be null",
    afterMapping.getAge());
    assertEquals("should map SuperClass.name to
    SubClassPrime userName.",request.getLoginName(),
    afterMapping.getUserName());
    assertEquals(request.getColor(),afterMapping.getColor
    ());
    assertEquals(request.getAge(), afterMapping.getAge());
    }

     
  • MJF

    MJF - 2006-07-17

    Logged In: YES
    user_id=1101499

    We've hit this one too...it's a pretty critical issue in
    our case. Our particular problem involves subclass mapping
    for a bean produced by a bean factory. Here's what I've
    been able to figure out. We're following this type of
    pattern:

    Case #1 - This works

    public abstract class sourceA
    public class sourceB extends sourceA

    public abstract class destA
    public class destB extends destA

    public class factoryA implements BeanFactoryIF (createBean
    produces an instance of destB)

    Mappings: bidirectional mappings exist for sourceA to destA
    (bean-factory=factoryA attached to sourceA), sourceB to
    destB.

    This scenario works perfectly for the following mappings:

    DozerBeanMapperSingletonWrapper.getInstance().map
    (sourceB,destA.class);

    Case #2 - The problem

    Now we introduce another class C that we want to map in the
    following fashion

    public class sourceC

    Mappings: bidirectional mappings exist for sourceC to destA
    (bean-factory=factoryA attached to sourceC), sourceC to
    destB

    This scenario produces an instance of sourceB (which we
    expect), but only populated with the superclass (sourceC to
    destA) mappings:

    DozerBeanMapperSingletonWrapper.getInstance().map
    (sourceC,destA.class);

    What I found is that in MappingProcessor.map(Object
    sourceObj, Class destClass, String mapId), the
    determineClassMap method is executed before the call to
    MappingUtils.createDestBean, so the mapping that you're
    working with may not match the actual instances you end up
    with (it all depends on whether or not your source is an
    abstract class or interface, forcing an invocation of
    walkDownSubclasses).

    When I injected the following code directly after the call
    to createDestBean to redetermine the map based on what the
    factory actually produced, things seemed to sort themselves
    out:

    if (destObj.getClass() != destClass) {
    classMap = determineClassMap(sourceObj, destObj.getClass
    (), mapId, false);
    }

    I had hoped to maybe use a listener to get this done in our
    code for now, but determineClassMap is a private method.

    If anyone really wants to see code samples behind this, I
    can put it together.

    - Matt

     
  • Matt Tierney

    Matt Tierney - 2006-11-13
    • assigned_to: nobody --> mhtierney
     
  • Matt Tierney

    Matt Tierney - 2007-04-25
    • assigned_to: mhtierney --> nobody
     
  • Franz Garsombke

    Franz Garsombke - 2007-05-03
    • assigned_to: nobody --> fgarsombke
     
  • Franz Garsombke

    Franz Garsombke - 2007-05-03

    Logged In: YES
    user_id=550744
    Originator: NO

    This looks like a good one. Let me see what I can come up with.

     
  • Franz Garsombke

    Franz Garsombke - 2007-05-05
    • status: open --> pending
     
  • Franz Garsombke

    Franz Garsombke - 2007-05-05

    Logged In: YES
    user_id=550744
    Originator: NO

    Fixed. I think... :). Checked into 3.x branch.

     
  • Franz Garsombke

    Franz Garsombke - 2007-05-21
    • status: pending --> closed
     
  • Perit Bezek

    Perit Bezek - 2007-07-19

    Logged In: YES
    user_id=1848652
    Originator: NO

    It seems that the fixation of this introduced another bug. As far as I know, to fix this bug, a default class map is created if one of the destination or source classes given in the mapping defininiton is different from the actual object classes (as in the case of mapping subclasses using a mapping for super classes). However this default mapping causes an override effect. For example if there is such a declaration in the mapping:
    <field>
    <a>propA.realProp</a>
    <b>propA</b>
    </field>
    MappingProcessor also maps propA to propA because of the default mapping, causing an override effect. Is there any way to bypass this, or should this be reported as a new bug?

     
  • Franz Garsombke

    Franz Garsombke - 2007-07-20

    Logged In: YES
    user_id=550744
    Originator: NO

    This sounds like a bug...I created defect 1757573 to track this. We will get this fixed for the next release.

    Thanks for looking.

    Franz

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks