Skip to content

Mapping collection with specific implementation #140

@djarnis73

Description

@djarnis73

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions