slayer
slayer

Reputation: 445

Unit test is failing while converting an entity to Immutable model object using Mapstruct

I am using MapStruct to convert a database entity to Immutable model object. So Immutable object doesn't have setters but Mapstruct requires setters when mapping objects. So I created an explicit builder using Immutable object builder to provides to Mapstruct. Below are the snippets from code:

@Value.Immutable
@Value.Style(overshadowImplementation = true)
public interface CarModel {
    @Nullable String getCarId();
}
@Mapper(uses = ImmutablesBuilderFactory.class)
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(source = "id", target = "carId")
    ImmutableCarModel.Builder toModel(CarEntity carEntity);
}
public class ImmutablesBuilderFactory {
    public ImmutableCarModel.Builder createCarModelBuilder() {
        return ImmutableCarModel.builder();
    }
}

Below code was generated by Mapstruct:

public class CarMapperImpl implements CarMapper {
    @Autowired
    private final ImmutablesBuilderFactory immutablesBuilderFactory
    @Override
    public Builder toModel(CarEntity carEntity) {
        if ( carEntity == null ) {
            return null;
        }
        Builder builder = immutablesBuilderFactory.createCarModelBuilder();
        if ( carEntity.getId() != null ) {
            builder.carId( carEntity.getId() );
        }
        return builder;
    }
}

I was able to convert an entity to Immutable model object but unit test is failing for this. It is throwing NPE at below line of code in CarMapperImpl class while calling CarMapper.INSTANCE.toModel(carEntity).build(); in unit test

Builder builder = immutablesBuilderFactory.createCarModelBuilder();

Does anyone have any idea what's going wrong here?

Upvotes: 0

Views: 281

Answers (2)

Filip
Filip

Reputation: 21423

The reason for the NPE is because you are mixing the usage of the default and spring component model.

The Mappers#getMapper is only meant to be used with the default component model. When using a dependency injection framework you need to use the framework to get access to the mapper.

Upvotes: 1

slayer
slayer

Reputation: 445

This was due to below property in MapStruct configuration

-Amapstruct.defaultComponentModel=spring

After removing this, Mapstruct was not autowiring and was able to create an instance of ImmutablesBuilderFactory.

Upvotes: 0

Related Questions