-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Hi
I had the need for a set with order retained, so I created beans that used the specific LinkedHashSet implementation instead of the Set interface.
This resulted in a runtime mapping error, since remap internally creates a HashSet and calls the setter, this leads to an IllegalArgumentException: argument type mismatch (it took me a while in the debugger to actually figure it out).
Example that fails (I use lombok for brevity):
public class RemapCollectionTest {
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class X {
LinkedHashSet<String> x = new LinkedHashSet<>();
}
@Test
public void testRemapperWithSpecificCollectionImpl() {
Mapper<X, X> mapper = Mapping
.from(X.class)
.to(X.class)
.mapper();
mapper.map(new X());
}
}
with
com.remondis.remap.MappingException: Invoking access method for property java.beans.PropertyDescriptor[name=x; propertyType=class java.util.LinkedHashSet; readMethod=public java.util.LinkedHashSet dk.danskespil.safe.aws.sqs.RemapCollectionTest$X.getX(); writeMethod=public void dk.danskespil.safe.aws.sqs.RemapCollectionTest$X.setX(java.util.LinkedHashSet)] failed.
at com.remondis.remap.MappingException.invocationFailed(MappingException.java:104)
at com.remondis.remap.Transformation.writeOrFail(Transformation.java:58)
at com.remondis.remap.ReassignTransformation.performTransformation(ReassignTransformation.java:52)
at com.remondis.remap.Transformation.performTransformation(Transformation.java:70)
at com.remondis.remap.ReassignTransformation.performTransformation(ReassignTransformation.java:23)
at com.remondis.remap.MappingConfiguration.map(MappingConfiguration.java:711)
at com.remondis.remap.MappingConfiguration.map(MappingConfiguration.java:691)
at com.remondis.remap.Mapper.map(Mapper.java:40)
at RemapCollectionTest.testRemapperWithSpecificCollectionImpl(RemapCollectionTest.java:28)
(junit part of stack trace snipped)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.remondis.remap.Transformation.writeOrFail(Transformation.java:54)
I worked around it by adding the following to the mapper:
.useMapper(TypeMapping.from(LinkedHashSet.class).to(LinkedHashSet.class).applying(x -> x))
But this means that I don't get a copy of the collection, which I can live with in my use case.
But, question is if there should be some extra checks to ensure that the used collection types are assignable or perhaps smart code that will use the destination type and instantiate the "correct" type instead of a HashSet.
Best regards Jens