I came to see a class in which @Mapping("this") was added to a field and a test method which checked that the source object and resulting object are not equal after invoking the map method in github's dozermapper.
As I cannot post the actual code, I am adding a similar class and test method below. (I have used lombok's @Data, @NoArgsConstructor and @AllArgsConstructor annotations to avoid explicitly specifying the getter, setter and constructors.)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestObj
{
private int id;
@Mapping("this")
private String name;
}
Test method :
@Test
public void testMapper() {
TestObj testObj = new TestObj(1, "test");
TestObj testCopy = DozerBeanMapperBuilder.create().build().map(testObj, TestObj.class);
Assert.assertNotEquals(testObj, testCopy);
}
The test was passed. If I remove @Mapping("this"), then the same test would fail. So how has the @Mapping("this") changed the mapping procedure so that the mapped object and source object are different?
@Mappingannotation is used when the field names in the source and destination class differ.For example, The below code would map the
fullNamefield in the source class object to thenamefield in the destination class object. This is particularly useful when you are mapping objects of two different classes.So if we use
@Mapping("this")on thenamefield, then it would map the source class itself to thenamefield. Here since thenameis of typeString, thetoString()representation of the source class would be mapped to thenamefield. An exception would be thrown if we have used an incompatible type likeintfor thenamefield. The source object itself would have been stored in thenamefield, if it was ofObjecttype or the same type as the source object.So, in the given question, the source and the destination class are the same, but the
@Mapping("this")is provided to thenamefield. So if the source object was likeTestObj(id=1,name="test"), then the mapped object would beTestObj(id=1,name="TestObj(id=1,name="test")", i.e thenamefield would be thetoString()of the source object. Hence both the objects would not be equal.If the
@Mapping("this")is removed, the test would fail because, the@Dataannotation adds anequals()method which checks the equality of individual fields and thus the source and mapped object would be equal.