Turn off "builders" in MapStruct when using Immutables
Asked Answered
G

3

15

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);
}
Gamaliel answered 12/2, 2019 at 17:25 Comment(0)
A
7

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

Appling answered 12/2, 2019 at 17:56 Comment(10)
I don't know why this did not work form me. I use Lombok with mapstruct 1.3.0.Final in Spring boot. I added a regular folder under resources : /resources/META-INF/services, under which i added a regular file named org.mapstruct.ap.spi.BuilderProvider. Into the file I only wrote : org.mapstruct.ap.spi.NoOpBuilderProvider. mapstruct still uses the Lombok builder in the generated resources. I even added the mapstruct-processor dependency because IntelliJ couldn't find org.mapstruct.ap. But still nothing.Jorgensen
Does it work with your build system? Do you have the annotationProcessorPaths in your maven-compiler-plugin (if you are using maven)Appling
yes I have annotationProcessorPaths set in the maven-compiler-plugin. In it i have 2 paths. One for mapstruct-processor and the other for lombokJorgensen
Can you try and remove them and add the processor as a provided dependency. Look at mapstruct/mapstruct#1713 that has a similar problem. The SPI is not picked up by the maven-compiler-plugin since it is not present on the annotation processor classpathAppling
In my case I have a single module (so a single POM file). I can't understand the changes that I need to do for that. I couldn't adapt the proposed PR for a single module projectJorgensen
That's the point if you are using a single module you would need to get rid of the annotationProcessorPaths and use a provided dependency of the mapstruct-processor in your dependenciesAppling
I will try it monday I give you feedbackJorgensen
thank you it worked. But why I still need to provide a builder name in the child class (I have a parent class with lombok builder and child one with a Lombok builder) ? Normally if mapstruct does not use it, it should not generate the exception Builder() in child class cannot override Builder() in parent class. I'm I missing something ?Jorgensen
Sorry I am not following. Can you please create another question with more details or ask in the Gitter room?Appling
will do it. Thank you for your helpJorgensen
R
51

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

Reahard answered 6/1, 2020 at 9:28 Comment(0)
A
7

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

Appling answered 12/2, 2019 at 17:56 Comment(10)
I don't know why this did not work form me. I use Lombok with mapstruct 1.3.0.Final in Spring boot. I added a regular folder under resources : /resources/META-INF/services, under which i added a regular file named org.mapstruct.ap.spi.BuilderProvider. Into the file I only wrote : org.mapstruct.ap.spi.NoOpBuilderProvider. mapstruct still uses the Lombok builder in the generated resources. I even added the mapstruct-processor dependency because IntelliJ couldn't find org.mapstruct.ap. But still nothing.Jorgensen
Does it work with your build system? Do you have the annotationProcessorPaths in your maven-compiler-plugin (if you are using maven)Appling
yes I have annotationProcessorPaths set in the maven-compiler-plugin. In it i have 2 paths. One for mapstruct-processor and the other for lombokJorgensen
Can you try and remove them and add the processor as a provided dependency. Look at mapstruct/mapstruct#1713 that has a similar problem. The SPI is not picked up by the maven-compiler-plugin since it is not present on the annotation processor classpathAppling
In my case I have a single module (so a single POM file). I can't understand the changes that I need to do for that. I couldn't adapt the proposed PR for a single module projectJorgensen
That's the point if you are using a single module you would need to get rid of the annotationProcessorPaths and use a provided dependency of the mapstruct-processor in your dependenciesAppling
I will try it monday I give you feedbackJorgensen
thank you it worked. But why I still need to provide a builder name in the child class (I have a parent class with lombok builder and child one with a Lombok builder) ? Normally if mapstruct does not use it, it should not generate the exception Builder() in child class cannot override Builder() in parent class. I'm I missing something ?Jorgensen
Sorry I am not following. Can you please create another question with more details or ask in the Gitter room?Appling
will do it. Thank you for your helpJorgensen
B
1

version

org.mapstruct:mapstruct-processor:1.5.5.Final

have some different

you can see source code in
org.mapstruct.ap.internal.util line 110

this.builderProvider = this.disableBuilder ?
  new NoOpBuilderProvider() :
  Services.get( BuilderProvider.class, defaultBuilderProvider );

So configuring spi about org.mapstruct.ap.spi.BuilderProvider file in the META-INF/services doesn't work anymore.

You must add processor compilerArgs in builde.gradle to make it choose 'NoOpBuilderProvider'

like this:

compileJava {
  options.compilerArgs += [
    '-Amapstruct.disableBuilders=true'
  ]
}
Bicorn answered 11/10, 2023 at 7:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.