MapStruct 1.3.0.Final. don't ignore non-getter-setter methods - mapstruct

I use Mapstruct and JOOQ for mapping between record-class and POJO. Today I tried to switch from Mapstruct 1.2.0.Final to 1.3.0.Final. But I get compilation errors like this - Unmapped target properties: "value1, value2, value3, value4".
JOOQ generate record-class with usual setters/getters and some public non-static methods with a name like valueN. valueN methods generates for each setter/getter.
With Mapstruct 1.2.0.Final it works perfectly fine. ValueN methods ignored in generated mappers. Generated mappers use only getters-setters. I didn't set ignore for ValueN explicitly.
How I can fix this behavior in Mapstruct 1.3.0.Final gracefully? How to configure Mapstruct for using only getters-setters?
Now I see two options:
Option 1.
Use #Mapping(target = "value1", ignore = true) for all valueN methods. Can I use some regexp pattern in target prop for ignore all valueN methods in single #Mapping?
Option 2.
Write my own AccessorNamingStrategy
Should I just choose one of the options above or Mapstruct has any config options for returning 1.2.0 behavior maybe?

In 1.3.0.Final in order to disable the fluent accessors you would have to go with option 1 or option 2 unfortunately.
If you go with option 2 then you can extend from DefaultAccessorNamingStrategy and then for isFluentSetter return false.

Or alternatively..
Option 2. Use #BeanMapping(ignoreByDefault = true) for all valueN methods.

Related

MapStruct: Issue with Nested Properties and ReportingPolicy.ERROR on Unmapped Source Properties

Using MapStruct, we want to use ReportingPolicy.ERROR, and have code like the following:
#Mapping(source = "nestedSource.doublyNestedSourceField", target = "nestedTarget.doublyNestedTargetField")
Target mapSourceToTarget(Source source);
Where nestedSource is not the same type as nestedTarget, and both doublyNested*Field types are String.
There is no mapper declared for NestedSource -> NestedTarget. The String properties declared in the Mapping above are the only ones in those types.
The above causes an unmapped source error:
Unmapped source property: "doublyNestedSourceField".
That seems more-or-less reasonable, as we didn't declare a mapper for NestedSource -> NestedTarget.
However, here's the issue: If we change the ReportingPolicy for unmapped sources to warn/ignore, MapStruct figures out how to correctly map the doublyNestedSourceField in the mapper implementation, even though it claims there is no source mapping present. Just wondering what is going on here, and whether I'm missing something.
----Into the weeds a bit more (in the MapStruct code itself)----
I could be doing something wrong, but I did notice that in BeanMethodMapping.java MapStruct attempts to remove "nestedSource.doubleNestedSourceField" from unprocessedSourceProperties, even though the key for the appropriate property is just "nestedSource" in unprocessedSourceProperties. Thus "nestedSource" is left as an unprocessed source property and an error is thrown.

Turn off "builders" in MapStruct when using Immutables

How do I completely disable using "builders" in MapStruct? I don't want to use them at all as they are causing all kinds of issues for me.
I created the service file under META-INF (I would prefer a way to assign it to the mapping builder= but I did not see any examples how to do it right in code).
It is still trying to use Immutables "builder" instance instance of the "ModifiableXXX" instance I want to map to. I'd even take a way of forcing it to the modifiable type if that is available.
In another mapping, using an update the ModifiableXXX (with #AfterMapping and #MappingTarget) approach works.
My mapper looks like this right now:
#Mapper
public interface MongoProjectMapper
{
ModifiableProject mapModel(MongoProject project);
#AfterMapping
ModifiableProject updateProject(MongoEntity e, #MappingTarget ModifiableProject p);
}
From Mapstruct version 1.3.1.Final we can use annotation org.mapstruct.Builder#disableBuilder within: #BeanMapping, #Mapper or #MapperConfig
#Mapper(builder = #Builder(disableBuilder = true))
public interface ProjectMapper
Have a look at #mapping-with-builders and documentation
Completely disabling builders is possible via the NoOpBuilderProvider. You need to create a org.mapstruct.ap.spi.BuilderProvider file in the META-INF/services directory with org.mapstruct.ap.spi.NoOpBuilderProvider as it’s content. This will completely disable the builders.
There is a feature request to make this more granular and disable it via #BeanMapping or on the mapper level. Have a look at mapstruct/mapstruct#1661

Can't map property String to JAXBElement<String> using MapStruct

so I was playing a bit with Mapstruct, reading the reference Documentation for the Version 1.1.0.Final, and arrived at the point:
implicit type conversions
where is defined the following statement:
Between JAXBElement < T> and T
I tried that, but the error what I received was:
Can't map property "java.lang.String xmlElement" "javax.xml.bind.JAXBElement<java.lang.String> xmlElement".
Consider to declare/implement a mapping method:
javax.xml.bind.JAXBElement<java.lang.String> map(java.lang.String value)".
I know thisi is the same thread asCan't map property when using MapStruct but since then Mapstruct released a new version.
Am I doing something wrong or this feature really is missing?
Thank you.
Mapping from JAXBElement<T> to T works out of the box. For the reverse you need to make sure that the ObjectFactory(ies) are in the Mapper#uses, MapStruct uses those methods to create the types.
You can also have a look at this integration test.
In case this happens on Java 9 or higher and you use implementation of type JAXBElement from maven library (in my case'javax.xml.bind:jaxb-api') make sure it is on the classpath of the annotation processor - this resolved the issue for me.
If your JAXBElement was generated by a wsdl client generator (eg. xjc) you need to provide the corresponding ObjectFactory.class generated by the client generator:
#Mapper(uses = ObjectFactory.class)
public interface OrderMapper {
Order orderEntityToExternalOrder(OrderEntity orderEntity);
}
See:
MapStruct 1.0.0.Beta1 is out with JAXB support, custom factories, decorators and more

Is there a global setting in Mapstruct that will trim a string value prior to setting it to a destination bean property

Is it possible to trim a string value before it is set against a bean property of type string in the destination bean?
Dozer offers such a facility through its mapping configuration for example,
<configuration>
<trim-strings>true</trim-strings>
</configuration>
Also see Dozer Global Configuration
With MapStruct 1.0.0.Final I can achieve this through Expressions or Before/After Mapping customization.
But wanted to know if there is a better way to handle such use cases.
Thanks in advance.
It appears MapStruct in its current form does not support this.
However one can achieve this effect with custom mapper methods, for example implement a class with a method that trims a String argument passed to it and then reference this class in the use attribute of the #Mapper annotation.
More at Invoking other mappers
If you require fine gained access control you could use
Selection based on Qualifiers
I was made aware of these approaches in response to a question I posted in mapstruct Google group
Example from #venkat-srinivasan answer's:
public class StringTrimmer {
public String trimString(String value) {
return value.trim();
}
}
and then in your mapper interface or class:
#Mapper(uses = StringTrimmer.class)
public interface MyMapper {

How to disable automapping of properties in Entity Framework

I've decided to use fluent mapping in Entity Framework. My intention was to map everyting by code without any atributes and auto mapping functions. Best way I've found is class EntityTypeConfiguration, that I implement for each entity in my project.
Later I add property to one of my entity. This property isn't needed to be persisted. I've expected, that until I add mapping for this property, it will be ignored by database and persistence layer. Unfortunatly it doesn't work that way, and property is mapped. Only way is to use Ignore method or NotMapped attribute, but I don't want to do it explicitly.
Is there any way, to stop Entity Framework from automapping? I've tried to remove all Conventions from DbModelBuilder, but it doesn't help.
So far as I am aware, there is no other way around it. You need to use either Ignore() or [NotMapped]. I tend to prefer the former as it does not clutter up the model.
Actually I have tried a lot of ways:
- custom convention to remove mapped properties
- removing all conventions
But the easiest (and cleanest) way was to use reflection inside the mapping class and to disable all property mappings that weren't configured.
The code for that (and also an usage example) is inside my public gist.
https://gist.github.com/hidegh/36d92380c720804dee043fde8a863ecb