I have a hard time working around modelmapper. Whenever a non trivial mapping is used an exception will be thrown.
In a nutshell i have:
ModelMapper m = new ModelMapper();
m.createTypeMap(Listing.class, Announce.class)
.addMapping(listing -> listing == null || listing.getLink() == null || StringUtils.isBlank(listing.getLink().getHref()) ? null : String.format("https://%s%s", domain, listing.getLink().getHref()), Announce::setLink);
And then further on
modelMapper.map(listing, Announce.class);
Which throws an exception:
2023-10-11 17:20:11.465 ERROR 12800 --- [pool-3-thread-1] b.c.f.c.application.Crawler : unpredicted error:
org.modelmapper.MappingException: ModelMapper mapping errors:
1) Error mapping br.com.a.b.model.c.Listing to br.com.a.b.model.a.Announce
1 error
at org.modelmapper.internal.Errors.throwMappingExceptionIfErrorsExist(Errors.java:386) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:80) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:589) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.ModelMapper.map(ModelMapper.java:422) ~[modelmapper-3.1.1.jar:na]
at br.com.a.b.application.Crawler.lambda$initializeCrawler$2(Crawler.java:143) ~[classes/:na]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Caused by: org.modelmapper.MappingException: ModelMapper mapping errors:
1) Failed to get value from br.com.a.b.model.c.Listing.getLink()
1 error
at org.modelmapper.internal.Errors.toMappingException(Errors.java:257) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.internal.PropertyInfoImpl$MethodAccessor.getValue(PropertyInfoImpl.java:104) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.internal.MappingEngineImpl.resolveSourceValue(MappingEngineImpl.java:197) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:170) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:151) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:105) ~[modelmapper-3.1.1.jar:na]
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:71) ~[modelmapper-3.1.1.jar:na]
... 9 common frames omitted
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.modelmapper.internal.PropertyInfoImpl$MethodAccessor.getValue(PropertyInfoImpl.java:99) ~[modelmapper-3.1.1.jar:na]
... 14 common frames omitted
The point is... if the source class doesn't have a getter that returns EXACTLY what you want to map, modelmapper won't work, so everytime that I have a complex mapping I always create the necessary getters and do whatever transformation I need in them [which is really wrong imho]
BUT IN THIS CASE I'M READING AN ENV VAR.
I don't want to inject an env var into a domain class because, so I need to do it without getters.
What can I do to solve this?
Following the suggestion from @Chaosfire and other stuff i saw online i added a custom converter
solved the problem