-1

I have a class A like:

A {
  ClassB b;
  String a;
}

Now there is another class X like:

X {
  ClassY y;
  String a;
}

Now, ClassY is same as ClassB, like:

ClassB/ClassY {
  String b;
}

I want to copy an instance of A into a new object of Y.

I came across Dozer which does similar mapping but that was if the values are primitive. I couldn't understand how to map the classes in them. Trying to do this in java.

I came across the answer https://stackoverflow.com/a/36196948/2733350 but I could not find MapperFactory in Dozer.

Destructor
  • 3,154
  • 7
  • 32
  • 51
  • is dozer your only option? or you are open to work something similar, like `mapstruct` ? – Andrei Sfat Dec 30 '17 at 22:21
  • Open to either of them. I will try this out – Destructor Dec 31 '17 at 06:37
  • 1
    I'm glad you found a solution to your problem. However, an actual answer/solution should **not** be edited into your Question. In general, you should [edit] the Question to *clarify the Question*, but not to include an Answer within the Question. You should create your own Answer with the code you used to solve your problem, then accept it (the system may require a 48 hour delay prior to accepting your own answer). When you have solved the problem yourself, [answering your own question is encouraged](//stackoverflow.com/help/self-answer). – Makyen Jan 02 '18 at 06:36
  • @Makyen: I added this as a answer but did not mark it accepted as I am not sure if that was the best way yet. Thanks for the suggestion :) – Destructor Jan 05 '18 at 10:51

2 Answers2

2

You can user MapStruct. It deals pretty okay with complex objects.

To follow your example, I have created a mapper that you can adjust accordingly (@Data comes from lombok):

@Data
public class A {

    private B b;
    private String a;
}

@Data
public class B {
    private String b;
}

@Data
public class Y {

    private String b;
}

And now you can define your actual mapper:

@Mapper
public interface AMapper {

    AMapper INSTANCE = Mappers.getMapper(AMapper.class);

    @Mapping(source = "b.b", target = "b")
    Y aToY(A a);
}

A small unit test:

@Test
public void shouldMapAToY() {
    A a = new A();
    a.setA("a variable");
    final B b = new B();
    b.setB("stuff from class b");
    a.setB(b);

    Y y = AMapper.INSTANCE.aToY(a);
    assertThat(y).isNotNull();
    assertThat(y.getB()).isEqualTo(b.getB());
}
Andrei Sfat
  • 8,440
  • 5
  • 49
  • 69
  • Thanks! That seems to be working but I am having few problems using in my project, dependency conflicts. I used ObjectMapper. – Destructor Dec 31 '17 at 10:16
1

BeanUtils from Apache Commons will do the trick:

copyProperties(Object, Object)

https://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/BeanUtils.html

Example code available from https://github.com/johanwitters/stackoverflow-copyProperties

package com.johanw.stackoverflow.copy;

public class ClassB {
    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    String b;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ClassB) && !(o instanceof ClassY)) return false;

        if (o instanceof ClassB) {
            ClassB classB = (ClassB) o;
            return b != null ? b.equals(classB.b) : classB.b == null;
        } else {
            ClassY classY = (ClassY) o;
            return b != null ? b.equals(classY.b) : classY.b == null;
        }
    }
}

package com.johanw.stackoverflow.copy;

public class ClassY {
    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    String b;
}

package com.johanw.stackoverflow.copy;

import org.apache.commons.beanutils.BeanUtils;
import org.junit.Assert;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;

public class TestCopy {
    @Test
    public void test() {
        ClassB b = new ClassB();
        b.b = "Hallo";
        ClassY y = new ClassY();
        try {
            Assert.assertFalse(b.equals(y));
            BeanUtils.copyProperties(b, y);
            Assert.assertTrue(b.equals(y));
        } catch (IllegalAccessException e) {
            Assert.fail(e.toString());
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            Assert.fail(e.toString());
            e.printStackTrace();
        }
    }
}

I hope this helps.

Johan Witters
  • 1,529
  • 11
  • 23