Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible types: CAP#1 cannot be converted to AdditionalRoutePointDTO where CAP#1 is a fresh type-variable: CAP#1 extends RoutePointDTO from capture of ? #3576

Closed
gkavv opened this issue Apr 25, 2024 · 7 comments
Labels

Comments

@gkavv
Copy link

gkavv commented Apr 25, 2024

Expected behavior

@Override
    public AdditionalRoutePointDTO additionalRoutePointToAdditionalRoutePointDTO(AdditionalRoutePoint additionalRoutePoint) {
        if ( additionalRoutePoint == null ) {
            return null;
        }

        AdditionalRoutePointDTO<?, ?> additionalRoutePointDTO = AdditionalRoutePointDTO.builder();

        additionalRoutePointDTO.id( additionalRoutePoint.getId() );
        additionalRoutePointDTO.sequence( additionalRoutePoint.getSequence() );
        additionalRoutePointDTO.datetime( additionalRoutePoint.getDatetime() );
        additionalRoutePointDTO.latitude( additionalRoutePoint.getLatitude() );
        additionalRoutePointDTO.longitude( additionalRoutePoint.getLongitude() );
        additionalRoutePointDTO.speed( additionalRoutePoint.getSpeed() );
        additionalRoutePointDTO.heading( additionalRoutePoint.getHeading() );
        additionalRoutePointDTO.minSpeed( additionalRoutePoint.getMinSpeed() );
        additionalRoutePointDTO.maxSpeed( additionalRoutePoint.getMaxSpeed() );

        return additionalRoutePointDTO.build();
    }

@Override
    public List<AdditionalRoutePointDTO> additionalRoutePointToAdditionalRoutePointDTO(List<AdditionalRoutePoint> additionalRoutePoints) {
        if ( additionalRoutePoints == null ) {
            return null;
        }

        List<AdditionalRoutePointDTO> list = new ArrayList<AdditionalRoutePointDTO>( additionalRoutePoints.size() );
        for ( AdditionalRoutePoint additionalRoutePoint : additionalRoutePoints ) {
            list.add( additionalRoutePointToAdditionalRoutePointDTO( additionalRoutePoint ) );
        }

        return list;
    }

Actual behavior

@Override
    public AdditionalRoutePointDTO additionalRoutePointToAdditionalRoutePointDTO(AdditionalRoutePoint additionalRoutePoint) {
        if ( additionalRoutePoint == null ) {
            return null;
        }

        RoutePointDTOBuilder<?, ?> additionalRoutePointDTO = RoutePointDTO.builder();

        additionalRoutePointDTO.id( additionalRoutePoint.getId() );
        additionalRoutePointDTO.sequence( additionalRoutePoint.getSequence() );
        additionalRoutePointDTO.datetime( additionalRoutePoint.getDatetime() );
        additionalRoutePointDTO.latitude( additionalRoutePoint.getLatitude() );
        additionalRoutePointDTO.longitude( additionalRoutePoint.getLongitude() );
        additionalRoutePointDTO.speed( additionalRoutePoint.getSpeed() );
        additionalRoutePointDTO.heading( additionalRoutePoint.getHeading() );
        additionalRoutePointDTO.minSpeed( additionalRoutePoint.getMinSpeed() );
        additionalRoutePointDTO.maxSpeed( additionalRoutePoint.getMaxSpeed() );

        return additionalRoutePointDTO.build();
    }

@Override
    public List<AdditionalRoutePointDTO> additionalRoutePointToAdditionalRoutePointDTO(List<AdditionalRoutePoint> additionalRoutePoints) {
        if ( additionalRoutePoints == null ) {
            return null;
        }

        List<AdditionalRoutePointDTO> list = new ArrayList<AdditionalRoutePointDTO>( additionalRoutePoints.size() );
        for ( AdditionalRoutePoint additionalRoutePoint : additionalRoutePoints ) {
            list.add( additionalRoutePointToAdditionalRoutePointDTO( additionalRoutePoint ) );
        }

        return list;
    }

Steps to reproduce the problem

Currently my mapper is as shown below. It was working fine before upgrading to Java 21 and Spring boot 3.
I am using also Lombok 1.18.30

@Mapper
public interface AdditionalRouteMapper {

	AdditionalRouteMapper INSTANCE = Mappers.getMapper(AdditionalRouteMapper.class);

	@Mapping(source = "additionalRoutePointDTOs", target = "points", qualifiedByName = "additionalRoutePointDTOs")
	@Mapping(target = "id", ignore = true)
	@Named("toAdditionalRoute")
	AdditionalRoute additionalRouteDTOToAdditionalRoute(AdditionalRouteDTO routeDto);

	@Mapping(source = "points", target = "additionalRoutePointDTOs", qualifiedByName = "points")
	@Named("toAdditionalRouteDTOs")
	AdditionalRouteDTO additionalRouteToAdditionalRouteDTO(AdditionalRoute additionalRoute);

	@Named("additionalRoutePointDTOs")
	default List<AdditionalRoutePoint> toAdditionalRoutePoints(List<AdditionalRoutePointDTO> additionalRoutePointDTOs) {
		List<AdditionalRoutePoint> additionalRoutePoints =
			AdditionalRoutePointMapper.INSTANCE.additionalRoutePointDTOToAdditionalRoutePoint(additionalRoutePointDTOs);
		return additionalRoutePoints;
	}

	@Named("additionalRoutePoints")
	default List<AdditionalRoutePointDTO> toAdditionalRoutePointDTOS(List<AdditionalRoutePoint> additionalRoutePoints) {
		List<AdditionalRoutePointDTO> additionalRoutePointDTOS =
			AdditionalRoutePointMapper.INSTANCE.additionalRoutePointToAdditionalRoutePointDTO(additionalRoutePoints);
		return additionalRoutePointDTOS;
	}
}


@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class AdditionalRoutePointDTO extends RoutePointDTO {

	private LegType legType;
	private String waypointName;
	private Integer waypointType;
	private Double portsideXtd;
	private Double starboardXtd;
	private Double turnRadius;
	private Double staticUkc;
	private Double dynamicUkc;
	private Double safetyContour;
	private Double safetyDepth;
	private String rtzWaypointExtension;
	private PointSource sourceType;
	private Double arrivalRadius;
	private String timeZone;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class AdditionalRoutePoint extends RoutePoint implements Serializable {
	private LegType legType;
	private String waypointName;
	private Integer waypointType;
	private Double portsideXtd;
	private Double starboardXtd;
	private Double turnRadius;
	private Double staticUkc;
	private Double dynamicUkc;
	private Double safetyContour;
	private Double safetyDepth;
	private String rtzWaypointExtension;
	private PointSource sourceType;
	private Double arrivalRadius;
	private String timeZone;
}


MapStruct Version

1.3.1.Final

@gkavv gkavv added the bug label Apr 25, 2024
@filiphr
Copy link
Member

filiphr commented Apr 27, 2024

@gkavv I see that you are using 1.3.1.Final. That is a really old version. Can you please try with the latest (1.5.5.Final) and let us know if it works?

@gkavv
Copy link
Author

gkavv commented Apr 29, 2024

@gkavv I see that you are using 1.3.1.Final. That is a really old version. Can you please try with the latest (1.5.5.Final) and let us know if it works?

I updated the version to 1.5.5.Final, but now I see different kind of errors:


[ERROR] /base/transport/mappers/AdditionalRouteMapper.java:[30,1] error: Qualifier error. No method found annotated with @Named#value: [ points ]. See https://mapstruct.org/faq/#qualifier for more info.
[ERROR] /base/transport/mappers/AdditionalRouteMapper.java:[30,1] error: Can't map property "List<AdditionalRoutePoint> points" to "List<AdditionalRoutePointDTO> additionalRoutePointDTOs". Consider to declare/implement a mapping method: "List<AdditionalRoutePointDTO> map(List<AdditionalRoutePoint> value)".
[ERROR] /base/domain/mapper/PlannedRoutePointMapper.java:[20,7] error: No implementation was created for PlannedRoutePointMapper due to having a problem in the erroneous element PlannedRoutePoint.PlannedRoutePointBuilder. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.
[ERROR] /base/transport/mappers/PlannedRouteMapper.java:[27,7] error: No implementation was created for PlannedRouteMapper due to having a problem in the erroneous element PlannedRouteDTO.PlannedRouteDTOBuilder. Hint: this often means that some other annotation processor was supposed to process the erroneous element. 

@filiphr
Copy link
Member

filiphr commented Apr 29, 2024

[ERROR] /base/transport/mappers/AdditionalRouteMapper.java:[30,1] error: Qualifier error. No method found annotated with @Named#value: [ points ]. See https://mapstruct.org/faq/#qualifier for more info.
[ERROR] /base/transport/mappers/AdditionalRouteMapper.java:[30,1] error: Can't map property "List<AdditionalRoutePoint> points" to "List<AdditionalRoutePointDTO> additionalRoutePointDTOs". Consider to declare/implement a mapping method: "List<AdditionalRoutePointDTO> map(List<AdditionalRoutePoint> value)".

Have you followed our release notes? This looks like you are using a qualifier somewhere, but no such qualifier could be found. It used to be ignore when a qualifier couldn't be found, but we changed this to have a compile error.

[ERROR] /base/domain/mapper/PlannedRoutePointMapper.java:[20,7] error: No implementation was created for PlannedRoutePointMapper due to having a problem in the erroneous element PlannedRoutePoint.PlannedRoutePointBuilder. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.
[ERROR] /base/transport/mappers/PlannedRouteMapper.java:[27,7] error: No implementation was created for PlannedRouteMapper due to having a problem in the erroneous element PlannedRouteDTO.PlannedRouteDTOBuilder. Hint: this often means that some other annotation processor was supposed to process the erroneous element. 

Those kind of errors are there when Lombok is being used. Are you using Lombok? If yes have you added the lombok-mapstruct-binding dependency?

@gkavv
Copy link
Author

gkavv commented Apr 29, 2024

[ERROR] /base/transport/mappers/AdditionalRouteMapper.java:[30,1] error: Qualifier error. No method found annotated with @Named#value: [ points ]. See https://mapstruct.org/faq/#qualifier for more info.
[ERROR] /base/transport/mappers/AdditionalRouteMapper.java:[30,1] error: Can't map property "List<AdditionalRoutePoint> points" to "List<AdditionalRoutePointDTO> additionalRoutePointDTOs". Consider to declare/implement a mapping method: "List<AdditionalRoutePointDTO> map(List<AdditionalRoutePoint> value)".

Have you followed our release notes? This looks like you are using a qualifier somewhere, but no such qualifier could be found. It used to be ignore when a qualifier couldn't be found, but we changed this to have a compile error.

[ERROR] /base/domain/mapper/PlannedRoutePointMapper.java:[20,7] error: No implementation was created for PlannedRoutePointMapper due to having a problem in the erroneous element PlannedRoutePoint.PlannedRoutePointBuilder. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.
[ERROR] /base/transport/mappers/PlannedRouteMapper.java:[27,7] error: No implementation was created for PlannedRouteMapper due to having a problem in the erroneous element PlannedRouteDTO.PlannedRouteDTOBuilder. Hint: this often means that some other annotation processor was supposed to process the erroneous element. 

Those kind of errors are there when Lombok is being used. Are you using Lombok? If yes have you added the lombok-mapstruct-binding dependency?

Yes I have tried with both having this dependency and without it. The error is exact the same.
On top of that, I see that this dependency hasn't been updated since 2020.
So, if this is needed after a specific release of mapstruct (since till now we didn't need it), I cannot understand how we can depend on a non-maintained dependency.

@filiphr
Copy link
Member

filiphr commented May 1, 2024

So, if this is needed after a specific release of mapstruct (since till now we didn't need it), I cannot understand how we can depend on a non-maintained dependency.

Have a look at our FAQ about using MapStruct and Lombok together. I would suggest that you use the latest Lombok dependency as well.

On top of that, I see that this dependency hasn't been updated since 2020.

The dependency is build by the Lombok team, not by the MapStruct team. It hasn't been updated because there is no need for it to be updated. If something is not being updated it does not mean that it is not maintained.


If updating Lombok and using the lombok-mapstruct-binding does not help then do what the error says and enable verbose mode.

Keep in mind that this is only for the "No implementation was created" error. The error about the qualifier is something else entirely, it has nothing to do with Lombok and everything to do with a mistake you have in your mappers

@gkavv
Copy link
Author

gkavv commented May 1, 2024

So, if this is needed after a specific release of mapstruct (since till now we didn't need it), I cannot understand how we can depend on a non-maintained dependency.

Have a look at our FAQ about using MapStruct and Lombok together. I would suggest that you use the latest Lombok dependency as well.

On top of that, I see that this dependency hasn't been updated since 2020.

The dependency is build by the Lombok team, not by the MapStruct team. It hasn't been updated because there is no need for it to be updated. If something is not being updated it does not mean that it is not maintained.

If updating Lombok and using the lombok-mapstruct-binding does not help then do what the error says and enable verbose mode.

Keep in mind that this is only for the "No implementation was created" error. The error about the qualifier is something else entirely, it has nothing to do with Lombok and everything to do with a mistake you have in your mappers

Lombok is in the latest version already, but again the "No implementation was created" error still appears.
For sure there is something in the code that is not compatible with the latest version.
I will check if the link helps.
Thanks

@gkavv gkavv closed this as completed May 15, 2024
@gkavv gkavv reopened this May 15, 2024
@gkavv
Copy link
Author

gkavv commented May 15, 2024

I fixed the issue.
Wasn't related to Lombok.
The source had to be changed as below in order to use @IterableMapping.

@Mapper
public interface AdditionalRouteMapper {

	AdditionalRouteMapper INSTANCE = Mappers.getMapper(AdditionalRouteMapper.class);

	@Mappings({@Mapping(target = "points", source = "additionalRoutePointDTOs"), @Mapping(target = "id", ignore = true)})
	@Named("toAdditionalRoute")
	AdditionalRoute additionalRouteDTOToAdditionalRoute(AdditionalRouteDTO routeDto);

	@Mappings({@Mapping(target = "additionalRoutePointDTOs", source = "points")})
	@Named("toAdditionalRouteDTOs")
	AdditionalRouteDTO additionalRouteToAdditionalRouteDTO(AdditionalRoute additionalRoute);

	@IterableMapping(qualifiedByName = "toAdditionalRoute")
	default List<AdditionalRoutePoint> toAdditionalRoutePoints(List<AdditionalRoutePointDTO> additionalRoutePointDTOs) {
		List<AdditionalRoutePoint> additionalRoutePoints =
			AdditionalRoutePointMapper.INSTANCE.additionalRoutePointDTOToAdditionalRoutePoint(additionalRoutePointDTOs);
		return additionalRoutePoints;
	}

	@IterableMapping(qualifiedByName = "toAdditionalRouteDTOs")
	default List<AdditionalRoutePointDTO> toAdditionalRoutePointDTOS(List<AdditionalRoutePoint> additionalRoutePoints) {
		List<AdditionalRoutePointDTO> additionalRoutePointDTOS =
			AdditionalRoutePointMapper.INSTANCE.additionalRoutePointToAdditionalRoutePointDTO(additionalRoutePoints);
		return additionalRoutePointDTOS;
	}
}

@gkavv gkavv closed this as completed May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants