Skip to content

Compilation error in generated code for @Conditional and collection  #2937

@dominik-seichter

Description

@dominik-seichter

When using mapstruct 1.5.2.Final and maven-compiler-plugin 3.8.1, we can produce a compilation error with the new @conditional feature (which is very much appreciated in general).

Assume a JPA entity class CustomerPerson which has a Set. Both should be mapped to CustomerPersonDTO containing a Set.

In our mapper, we have added code to prevent mapping addresses, when they are lazy from hibernate (see #2776)

@Mapper(uses = { CustomerAddressMapper.class }, config = MapStructConfiguration.class)
public interface CustomerPersonMapper {

	CustomerPersonDTO toDTO(final CustomerPerson entity);
	CustomerPerson toEntity(final CustomerPersonDTO dto);
	
	@Condition
    default boolean isLazyLoaded(Collection<?> sourceCollection) {

        // Case: Source field in domain object is lazy: Skip mapping
        if (!Hibernate.isInitialized(sourceCollection)) {
            // Skip mapping, as resetting the custom converter is not thread safe!
            return true;
        }

        // Continue mapping
        return false;
	
	}
}

Now the generated code in CustomerPersonMapperImpl contains a compilation error:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project mapstruct-bug: Compilation failure: Compilation failure:
[ERROR] /C:/gefa/git/gefa-incubator/mapstruct-bug/target/generated-sources/annotations/com/accenture/hpsapf/masterdatamanagement/mapper/CustomerPersonMapperImpl.java:[30,28] cannot find symbol
[ERROR]   symbol:   variable address
[ERROR]   location: class com.accenture.hpsapf.masterdatamanagement.mapper.CustomerPersonMapperImpl
[ERROR] /C:/gefa/git/gefa-incubator/mapstruct-bug/target/generated-sources/annotations/com/accenture/hpsapf/masterdatamanagement/mapper/CustomerPersonMapperImpl.java:[50,28] cannot find symbol
[ERROR]   symbol:   variable address
[ERROR]   location: class com.accenture.hpsapf.masterdatamanagement.mapper.CustomerPersonMapperImpl
[ERROR] -> [Help 1]

Reason is, that the lines are generated wrongly (or something with our usage of @conditional is not correct):

...
 customerPersonDTO.setBirthday( entity.getBirthday() );
        if ( isLazyLoaded( address ) ) { /// <---- COMPILATION ERROR HERE, addresses is not known
            for ( CustomerAddress address : entity.getAddresses() ) {
                customerPersonDTO.addCustomerAddress( customerAddressMapper.toDTO( address ) );
            }
        }

In our opinion the generated code should look like this:

 customerPersonDTO.setBirthday( entity.getBirthday() );
        if ( isLazyLoaded( entity.getAddresses() ) ) {
            for ( CustomerAddress address : entity.getAddresses() ) {
                customerPersonDTO.addCustomerAddress( customerAddressMapper.toDTO( address ) );
            }
        }

You can find a self-contained simple maven test case to reproduce the issue attached:
mapstruct-bug.zip

Is this a known issue? We could not find any similar reports.
Is there a workaround or a different usage for @conditional?

Thanks!
Dominik

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions