S6856 FP with binding via @ModelAttribute

Setup:

  • JDK 25, Lombok 1.18.42 (provided scope)

  • Maven 3.9.12, Sonar scanner for Maven 5.5.0.6356

  • SonarQube Cloud

I have a composite type bound to a Spring controller method using the @ModelAttribute annotation:

@PostMapping("/{orderIdType}/{orderIdValue}/ship-info/{shipToId}/actions/update-ship-fees")
public ResponseEntity<OrderResponse> updateFees(
        @ModelAttribute OrderIdentifier orderId,
        @PathVariable String shipToId,
        @Valid @RequestBody UpdateShipInfoResource request) {

The variables orderIdType and orderIdValue are bound from the model using @BindParam:

public record OrderIdentifier(

    @BindParam("orderIdType")
    Type type,

    @BindParam("orderIdValue")
    String value
)

Sonar is complaining about the component fields in the @PostMapping:

Bind template variable “orderIdValue”, “orderIdType” to a method parameter.

If there isn’t a way to get Sonar to examine the model itself, is there a better way to suppress this than either annotating every controller method, or adding a broad package-level suppression that might mask other genuine problems?

1 Like

Hi Jack, indeed we do not support (yet) this way of binding path variables to a model attribute.
I don’t know of another way of suppressing the noise other than disabling the rule altogether, or one of the solutions you mentioned :frowning:

I created a ticket with a small reproducer for future improvements, thanks a lot for the report!

1 Like

Thanks, I’ll add the individual suppressions per method then… I’m loathe to disable the rule altogether, or even disable it at controller level, as for other forms of binding it’s pretty useful.

I’ll keep an eye on that ticket!

Oh, minor detail, but it’s not record-specific - you can use @BindParam on constructor args for any arbitrary class, so a full fix would examine not just the controller method args but also, for any arg marked with @ModelAttribute, the constructor args for its type.

@BindParam then lets you modify the name, which can be helpful to avoid stutter (and smooth over the differences in boolean conventions between classes and records) in some cases such as mine. If it’s not present, I believe the constructor arg name is directly matched to the query (or path) param.

1 Like