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?
@Mapping
annotation is used when the field names in the source and destination class differ.
For example, The below code would map the fullName
field in the source class object to the name
field in the destination class object. This is particularly useful when you are mapping objects of two different classes.
@Mapping("fullName")
private int name;
So if we use @Mapping("this")
on the name
field, then it would map the source class itself to the name
field. Here since the name
is of type String
, the toString()
representation of the source class would be mapped to the name
field. An exception would be thrown if we have used an incompatible type like int
for the name
field. The source object itself would have been stored in the name
field, if it was of Object
type 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 the name
field. So if the source object was like TestObj(id=1,name="test")
, then the mapped object would be TestObj(id=1,name="TestObj(id=1,name="test")"
, i.e the name
field would be the toString()
of the source object. Hence both the objects would not be equal.
If the @Mapping("this")
is removed, the test would fail because, the @Data
annotation adds an equals()
method which checks the equality of individual fields and thus the source and mapped object would be equal.