mapstruct-idea icon indicating copy to clipboard operation
mapstruct-idea copied to clipboard

Converter implementation is not refreshed in IDEA

Open ThanksForAllTheFish opened this issue 8 years ago • 10 comments

Using https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-lombok as a reference, I tried to add a field to both Source and Target and then modified the test to cover the new field.

@Test
public void testMapping() {
    Source s = new Source();
    s.setTest( "5" );
    s.setField( "5" );

    Target t = Mappers.getMapper(SourceTargetMapper.class).toTarget( s );
    assertEquals( 5, (long) t.getTesting() );
    assertEquals( "5", t.getField() );
}

However this leads to the test to fail, being t.getField() still null.

Another relevant change I did (which I am not sure about) is to add mapstruct-processor to the compile configuration in build.gradle, ie: compile "org.mapstruct:mapstruct-jdk8:${mapstructVersion}", "org.mapstruct:mapstruct-processor:${mapstructVersion}", "org.projectlombok:lombok:${lombokVersion}" as per http://mapstruct.org/documentation/ide-support/

Also removing a field from both objects leads to an error, this time a java.lang.NoSuchMethodError.

Versions used:

  • IDEA 2017.2.5 (with annotation processor manually enabled, no other customization)
  • lombok 1.16.18 (instead of 1.16.14)

ThanksForAllTheFish avatar Oct 11 '17 14:10 ThanksForAllTheFish

@ThanksForAllTheFish I don't think that this is linked to the IntelliJ plugin. In any case, can you check that the generated class contains the new mapping? It might be possible that IntelliJ does not invoke the processor when you change some of the other classes.

Have you tried delegating the build to gradle?

filiphr avatar Oct 15 '17 12:10 filiphr

It seems you are actually right:

  • if I change the mapper, the generated implementation (SourceTargetMapperImpl) is updated
  • if I change source and target classes, the mapper is NOT updated
  • delegating to gradle, the implementation is updated either way (but since IDEA 2017.2 gradle and IDEA output directories are different, it probably makes sense to use gradle-idea plugin as well so to be able to configure source sets correctly)

ThanksForAllTheFish avatar Oct 16 '17 07:10 ThanksForAllTheFish

Did you have a chance to look at this?

ThanksForAllTheFish avatar Nov 22 '17 08:11 ThanksForAllTheFish

@ThanksForAllTheFish I have actually had a look into this. Unfortunately, I am not entirely sure if we as a plugin can do something about this. The reason why you are seeing that behaviour is due to the way that compilation works in IDEA.

IDEA Only compiles the classes that have been changed since the last build, and when you change Source or Target only then SourceTargetMapper won't be compiled. Maybe we need to raise an issue with Jetbrains.

I as well am not that well knowledgeable of the internals of IDEA and if someone has an idea or is willing to help out with this I am more than happy to tag along. I've asked on twitter, let's see if we get some more info

filiphr avatar Nov 22 '17 18:11 filiphr

Any news on this topic? This keeps happening

lvalladares avatar Sep 24 '19 21:09 lvalladares

@lvalladares the status from my previous comment has not changed. I don't know the internals of IDEA that well in order to know what we can do about this.

filiphr avatar Sep 26 '19 18:09 filiphr

Manually recompiling the Mapper interface will regenerate the mapper implementation too. But this is also not the expected way to do it.

There is the possibility to listen on file changes and handle them, i used that in a plugin. But that would be low level on the file system api and not the best way for this use case.

The change on the java class reflected in the psi tree would be the point i would start to look at. Maybe there is something in the api that can track the link between the annotated mapper interfaces (any used bean type in it) and the beans that are changed in structure.

mkrumpholz avatar Jun 30 '20 15:06 mkrumpholz

I agree with all you said @mkrumpholz. I've tried looking into this, and I would want to avoid listening on any changes. In my opinion this is the job of the IDE. It should track from where a file was generated and then update recompile the mapper. This is what Eclipse and Gradle does for their incremental compilation.

filiphr avatar Jul 04 '20 17:07 filiphr

IDEA keeps track of the changed files, the thing to search and implement may be a trigger to add dependent files to the changelist. I can't provide the code for this as i didn't implement such case yet. Maybe the docs are good enough now to find some more hints on how to implement this? The custom language plugin may be a good starting point as such plugins will go deeper into the wohle apis of IDEA.

mkrumpholz avatar Jul 06 '20 08:07 mkrumpholz

Has anyone found any workarounds other than editing the mapper to force an update?

bluprince13 avatar Oct 16 '22 10:10 bluprince13